diff options
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/proxy/plugin_dispatcher.cc | 20 | ||||
-rw-r--r-- | ppapi/proxy/ppb_core_proxy.cc | 6 | ||||
-rw-r--r-- | ppapi/proxy/ppb_flash_proxy.cc | 13 | ||||
-rw-r--r-- | ppapi/proxy/ppb_message_loop_proxy.cc | 8 | ||||
-rw-r--r-- | ppapi/proxy/ppb_testing_proxy.cc | 11 | ||||
-rw-r--r-- | ppapi/proxy/ppb_var_deprecated_proxy.cc | 19 | ||||
-rw-r--r-- | ppapi/proxy/ppp_class_proxy.cc | 29 | ||||
-rw-r--r-- | ppapi/proxy/ppp_graphics_3d_proxy.cc | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppp_input_event_proxy.cc | 9 | ||||
-rw-r--r-- | ppapi/proxy/ppp_instance_private_proxy.cc | 6 | ||||
-rw-r--r-- | ppapi/proxy/ppp_instance_private_proxy_unittest.cc | 2 | ||||
-rw-r--r-- | ppapi/proxy/ppp_messaging_proxy.cc | 7 | ||||
-rw-r--r-- | ppapi/proxy/ppp_mouse_lock_proxy.cc | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppp_video_decoder_proxy.cc | 25 | ||||
-rw-r--r-- | ppapi/proxy/serialized_var_unittest.cc | 8 | ||||
-rw-r--r-- | ppapi/shared_impl/ppp_instance_combined.cc | 24 | ||||
-rw-r--r-- | ppapi/shared_impl/proxy_lock.cc | 5 | ||||
-rw-r--r-- | ppapi/shared_impl/proxy_lock.h | 75 | ||||
-rw-r--r-- | ppapi/shared_impl/tracked_callback.cc | 9 | ||||
-rw-r--r-- | ppapi/thunk/enter.cc | 18 | ||||
-rw-r--r-- | ppapi/thunk/enter.h | 2 |
21 files changed, 235 insertions, 71 deletions
diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index efe0803..bfa7917 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,6 +25,7 @@ #include "ppapi/proxy/ppb_instance_proxy.h" #include "ppapi/proxy/ppp_class_proxy.h" #include "ppapi/proxy/resource_creation_proxy.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/resource.h" #if defined(OS_POSIX) @@ -52,8 +53,11 @@ InstanceData::InstanceData() InstanceData::~InstanceData() { // Run any pending mouse lock callback to prevent leaks. - if (mouse_lock_callback.func) - PP_RunAndClearCompletionCallback(&mouse_lock_callback, PP_ERROR_ABORTED); + if (mouse_lock_callback.func) { + CallWhileUnlocked(PP_RunAndClearCompletionCallback, + &mouse_lock_callback, + static_cast<int32_t>(PP_ERROR_ABORTED)); + } } PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle, @@ -164,17 +168,25 @@ bool PluginDispatcher::Send(IPC::Message* msg) { "Class", IPC_MESSAGE_ID_CLASS(msg->type()), "Line", IPC_MESSAGE_ID_LINE(msg->type())); // We always want plugin->renderer messages to arrive in-order. If some sync - // and some async messages are send in response to a synchronous + // and some async messages are sent in response to a synchronous // renderer->plugin call, the sync reply will be processed before the async // reply, and everything will be confused. // // Allowing all async messages to unblock the renderer means more reentrancy // there but gives correct ordering. msg->set_unblock(true); + if (msg->is_sync()) { + // Synchronous messages might be re-entrant, so we need to drop the lock. + ProxyAutoUnlock unlock; + return Dispatcher::Send(msg); + } return Dispatcher::Send(msg); } bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { + // We need to grab the proxy lock to ensure that we don't collide with the + // plugin making pepper calls on a different thread. + ProxyAutoLock lock; TRACE_EVENT2("ppapi proxy", "PluginDispatcher::OnMessageReceived", "Class", IPC_MESSAGE_ID_CLASS(msg.type()), "Line", IPC_MESSAGE_ID_LINE(msg.type())); diff --git a/ppapi/proxy/ppb_core_proxy.cc b/ppapi/proxy/ppb_core_proxy.cc index 842ed86..14e9b83 100644 --- a/ppapi/proxy/ppb_core_proxy.cc +++ b/ppapi/proxy/ppb_core_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -55,7 +55,7 @@ void CallbackWrapper(PP_CompletionCallback callback, int32_t result) { TRACE_EVENT2("ppapi proxy", "CallOnMainThread callback", "Func", reinterpret_cast<void*>(callback.func), "UserData", callback.user_data); - PP_RunCompletionCallback(&callback, result); + CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); } void CallOnMainThread(int delay_in_ms, @@ -63,7 +63,7 @@ void CallOnMainThread(int delay_in_ms, int32_t result) { GetMainThreadMessageLoop()->PostDelayedTask( FROM_HERE, - base::Bind(&CallbackWrapper, callback, result), + RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)), delay_in_ms); } diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc index 19eabcf..bcd692b 100644 --- a/ppapi/proxy/ppb_flash_proxy.cc +++ b/ppapi/proxy/ppb_flash_proxy.cc @@ -20,6 +20,7 @@ #include "ppapi/proxy/proxy_module.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/resource_tracker.h" #include "ppapi/shared_impl/scoped_pp_resource.h" @@ -34,6 +35,7 @@ namespace proxy { namespace { void SetInstanceAlwaysOnTop(PP_Instance pp_instance, PP_Bool on_top) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(pp_instance); if (dispatcher) { dispatcher->Send(new PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop( @@ -52,6 +54,7 @@ PP_Bool DrawGlyphs(PP_Instance instance, uint32_t glyph_count, const uint16_t glyph_indices[], const PP_Point glyph_advances[]) { + ProxyAutoLock lock; Resource* image_data = PpapiGlobals::Get()->GetResourceTracker()->GetResource(pp_image_data); if (!image_data) @@ -101,13 +104,14 @@ PP_Bool DrawGlyphs11(PP_Instance instance, uint32_t glyph_count, const uint16_t glyph_indices[], const PP_Point glyph_advances[]) { - // Backwards-compatible version. + // Backwards-compatible version. DrawGlyphs locks; no need to lock here. return DrawGlyphs(instance, pp_image_data, font_desc, color, &position, &clip, transformation, PP_TRUE, glyph_count, glyph_indices, glyph_advances); } PP_Var GetProxyForURL(PP_Instance instance, const char* url) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return PP_MakeUndefined(); @@ -141,11 +145,12 @@ int32_t Navigate(PP_Resource request_id, int32_t Navigate11(PP_Resource request_id, const char* target, bool from_user_action) { - // Backwards-compatible version. + // Backwards-compatible version. Navigate locks; no need to lock here. return Navigate(request_id, target, PP_FromBool(from_user_action)); } void RunMessageLoop(PP_Instance instance) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return; @@ -156,6 +161,7 @@ void RunMessageLoop(PP_Instance instance) { } void QuitMessageLoop(PP_Instance instance) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return; @@ -164,6 +170,7 @@ void QuitMessageLoop(PP_Instance instance) { } double GetLocalTimeZoneOffset(PP_Instance instance, PP_Time t) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return 0.0; @@ -181,11 +188,13 @@ double GetLocalTimeZoneOffset(PP_Instance instance, PP_Time t) { } PP_Var GetCommandLineArgs(PP_Module /*pp_module*/) { + ProxyAutoLock lock; std::string args = ProxyModule::GetInstance()->GetFlashCommandLineArgs(); return StringVar::StringToPPVar(args); } void PreLoadFontWin(const void* logfontw) { + ProxyAutoLock lock; PluginGlobals::Get()->plugin_proxy_delegate()->PreCacheFont(logfontw); } diff --git a/ppapi/proxy/ppb_message_loop_proxy.cc b/ppapi/proxy/ppb_message_loop_proxy.cc index 12a48bb..7a64b50 100644 --- a/ppapi/proxy/ppb_message_loop_proxy.cc +++ b/ppapi/proxy/ppb_message_loop_proxy.cc @@ -55,6 +55,9 @@ class MessageLoopResource : public Resource, public PPB_MessageLoop_API { // Handles posting to the message loop if there is one, or the pending queue // if there isn't. + // NOTE: The given closure will be run *WITHOUT* acquiring the Proxy lock. + // This only makes sense for user code and completely thread-safe + // proxy operations (e.g., MessageLoop::QuitClosure). void PostClosure(const tracked_objects::Location& from_here, const base::Closure& closure, int64 delay_ms); @@ -197,8 +200,9 @@ void MessageLoopResource::PostClosure( const base::Closure& closure, int64 delay_ms) { if (loop_.get()) { - loop_->PostDelayedTask( - from_here, closure, base::TimeDelta::FromMilliseconds(delay_ms)); + loop_->PostDelayedTask(from_here, + closure, + base::TimeDelta::FromMilliseconds(delay_ms)); } else { TaskInfo info; info.from_here = FROM_HERE; diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc index 9c0a14b..629b3f0 100644 --- a/ppapi/proxy/ppb_testing_proxy.cc +++ b/ppapi/proxy/ppb_testing_proxy.cc @@ -10,13 +10,14 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/resource_tracker.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_input_event_api.h" using ppapi::thunk::EnterInstance; -using ppapi::thunk::EnterResource; +using ppapi::thunk::EnterResourceNoLock; using ppapi::thunk::PPB_InputEvent_API; namespace ppapi { @@ -27,6 +28,7 @@ namespace { PP_Bool ReadImageData(PP_Resource graphics_2d, PP_Resource image, const PP_Point* top_left) { + ProxyAutoLock lock; Resource* image_object = PpapiGlobals::Get()->GetResourceTracker()->GetResource(image); if (!image_object) @@ -50,6 +52,7 @@ PP_Bool ReadImageData(PP_Resource graphics_2d, } void RunMessageLoop(PP_Instance instance) { + // TODO(dmichael): We should probably assert that this is the main thread. bool old_state = MessageLoop::current()->NestableTasksAllowed(); MessageLoop::current()->SetNestableTasksAllowed(true); MessageLoop::current()->Run(); @@ -57,10 +60,12 @@ void RunMessageLoop(PP_Instance instance) { } void QuitMessageLoop(PP_Instance instance) { + // TODO(dmichael): We should probably assert that this is the main thread. MessageLoop::current()->QuitNow(); } uint32_t GetLiveObjectsForInstance(PP_Instance instance_id) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); if (!dispatcher) return static_cast<uint32_t>(-1); @@ -76,10 +81,11 @@ PP_Bool IsOutOfProcess() { } void SimulateInputEvent(PP_Instance instance_id, PP_Resource input_event) { + ProxyAutoLock lock; PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance_id); if (!dispatcher) return; - EnterResource<PPB_InputEvent_API> enter(input_event, false); + EnterResourceNoLock<PPB_InputEvent_API> enter(input_event, false); if (enter.failed()) return; @@ -99,6 +105,7 @@ PP_Var GetDocumentURL(PP_Instance instance, PP_URLComponents_Dev* components) { // host-side tracker when running out-of-process, to make sure the proxy does // not leak host-side vars. uint32_t GetLiveVars(PP_Var live_vars[], uint32_t array_size) { + ProxyAutoLock lock; std::vector<PP_Var> vars = PpapiGlobals::Get()->GetVarTracker()->GetLiveVars(); for (size_t i = 0u; diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc index f62e220c..fbd6ef9 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.cc +++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -22,6 +22,7 @@ #include "ppapi/proxy/ppp_class_proxy.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/shared_impl/ppb_var_shared.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/var.h" namespace ppapi { @@ -64,6 +65,7 @@ PluginDispatcher* CheckExceptionAndGetDispatcher(const PP_Var& object, bool HasProperty(PP_Var var, PP_Var name, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); if (!dispatcher) return false; @@ -82,6 +84,7 @@ bool HasProperty(PP_Var var, bool HasMethod(PP_Var var, PP_Var name, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); if (!dispatcher) return false; @@ -100,6 +103,7 @@ bool HasMethod(PP_Var var, PP_Var GetProperty(PP_Var var, PP_Var name, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); if (!dispatcher) return PP_MakeUndefined(); @@ -119,6 +123,7 @@ void EnumerateProperties(PP_Var var, uint32_t* property_count, PP_Var** properties, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); if (!dispatcher) { *property_count = 0; @@ -141,6 +146,7 @@ void SetProperty(PP_Var var, PP_Var name, PP_Var value, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); if (!dispatcher) return; @@ -158,6 +164,7 @@ void SetProperty(PP_Var var, void RemoveProperty(PP_Var var, PP_Var name, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); if (!dispatcher) return; @@ -177,6 +184,7 @@ PP_Var Call(PP_Var object, uint32_t argc, PP_Var* argv, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception); if (!dispatcher) return PP_MakeUndefined(); @@ -200,6 +208,7 @@ PP_Var Construct(PP_Var object, uint32_t argc, PP_Var* argv, PP_Var* exception) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception); if (!dispatcher) return PP_MakeUndefined(); @@ -221,6 +230,7 @@ PP_Var Construct(PP_Var object, bool IsInstanceOf(PP_Var var, const PPP_Class_Deprecated* ppp_class, void** ppp_class_data) { + ProxyAutoLock lock; Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, NULL); if (!dispatcher) return false; @@ -239,6 +249,7 @@ bool IsInstanceOf(PP_Var var, PP_Var CreateObject(PP_Instance instance, const PPP_Class_Deprecated* ppp_class, void* ppp_class_data) { + ProxyAutoLock lock; Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return PP_MakeUndefined(); @@ -367,9 +378,9 @@ void PPB_Var_Deprecated_Proxy::OnMsgReleaseObject(int64 object_id) { // TODO(piman): See if we can fix the IPC code to enforce strict ordering, and // then remove this. MessageLoop::current()->PostNonNestableTask(FROM_HERE, - base::Bind(&PPB_Var_Deprecated_Proxy::DoReleaseObject, - task_factory_.GetWeakPtr(), - object_id)); + RunWhileLocked(base::Bind(&PPB_Var_Deprecated_Proxy::DoReleaseObject, + task_factory_.GetWeakPtr(), + object_id))); } void PPB_Var_Deprecated_Proxy::OnMsgHasProperty( diff --git a/ppapi/proxy/ppp_class_proxy.cc b/ppapi/proxy/ppp_class_proxy.cc index 0ff8973..91f44cb 100644 --- a/ppapi/proxy/ppp_class_proxy.cc +++ b/ppapi/proxy/ppp_class_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,6 +8,7 @@ #include "ppapi/c/dev/ppp_class_deprecated.h" #include "ppapi/proxy/dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/shared_impl/api_id.h" @@ -243,23 +244,28 @@ void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class, int64 object, SerializedVarReceiveInput property, SerializedVarOutParam exception, bool* result) { - *result = ToPPPClass(ppp_class)->HasProperty(ToUserData(object), - property.Get(dispatcher()), exception.OutParam(dispatcher())); + *result = CallWhileUnlocked(ToPPPClass(ppp_class)->HasProperty, + ToUserData(object), + property.Get(dispatcher()), + exception.OutParam(dispatcher())); } void PPP_Class_Proxy::OnMsgHasMethod(int64 ppp_class, int64 object, SerializedVarReceiveInput property, SerializedVarOutParam exception, bool* result) { - *result = ToPPPClass(ppp_class)->HasMethod(ToUserData(object), - property.Get(dispatcher()), exception.OutParam(dispatcher())); + *result = CallWhileUnlocked(ToPPPClass(ppp_class)->HasMethod, + ToUserData(object), + property.Get(dispatcher()), + exception.OutParam(dispatcher())); } void PPP_Class_Proxy::OnMsgGetProperty(int64 ppp_class, int64 object, SerializedVarReceiveInput property, SerializedVarOutParam exception, SerializedVarReturnValue result) { - result.Return(dispatcher(), ToPPPClass(ppp_class)->GetProperty( + result.Return(dispatcher(), CallWhileUnlocked( + ToPPPClass(ppp_class)->GetProperty, ToUserData(object), property.Get(dispatcher()), exception.OutParam(dispatcher()))); } @@ -276,7 +282,7 @@ void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class, int64 object, SerializedVarReceiveInput property, SerializedVarReceiveInput value, SerializedVarOutParam exception) { - ToPPPClass(ppp_class)->SetProperty( + CallWhileUnlocked(ToPPPClass(ppp_class)->SetProperty, ToUserData(object), property.Get(dispatcher()), value.Get(dispatcher()), exception.OutParam(dispatcher())); } @@ -284,7 +290,7 @@ void PPP_Class_Proxy::OnMsgSetProperty(int64 ppp_class, int64 object, void PPP_Class_Proxy::OnMsgRemoveProperty(int64 ppp_class, int64 object, SerializedVarReceiveInput property, SerializedVarOutParam exception) { - ToPPPClass(ppp_class)->RemoveProperty( + CallWhileUnlocked(ToPPPClass(ppp_class)->RemoveProperty, ToUserData(object), property.Get(dispatcher()), exception.OutParam(dispatcher())); } @@ -297,7 +303,7 @@ void PPP_Class_Proxy::OnMsgCall( SerializedVarReturnValue result) { uint32_t arg_count = 0; PP_Var* args = arg_vector.Get(dispatcher(), &arg_count); - result.Return(dispatcher(), ToPPPClass(ppp_class)->Call( + result.Return(dispatcher(), CallWhileUnlocked(ToPPPClass(ppp_class)->Call, ToUserData(object), method_name.Get(dispatcher()), arg_count, args, exception.OutParam(dispatcher()))); } @@ -309,12 +315,13 @@ void PPP_Class_Proxy::OnMsgConstruct( SerializedVarReturnValue result) { uint32_t arg_count = 0; PP_Var* args = arg_vector.Get(dispatcher(), &arg_count); - result.Return(dispatcher(), ToPPPClass(ppp_class)->Construct( + result.Return(dispatcher(), CallWhileUnlocked( + ToPPPClass(ppp_class)->Construct, ToUserData(object), arg_count, args, exception.OutParam(dispatcher()))); } void PPP_Class_Proxy::OnMsgDeallocate(int64 ppp_class, int64 object) { - ToPPPClass(ppp_class)->Deallocate(ToUserData(object)); + CallWhileUnlocked(ToPPPClass(ppp_class)->Deallocate, ToUserData(object)); } } // namespace proxy diff --git a/ppapi/proxy/ppp_graphics_3d_proxy.cc b/ppapi/proxy/ppp_graphics_3d_proxy.cc index d83aa80..8143f31 100644 --- a/ppapi/proxy/ppp_graphics_3d_proxy.cc +++ b/ppapi/proxy/ppp_graphics_3d_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,6 +8,7 @@ #include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { namespace proxy { @@ -65,7 +66,7 @@ bool PPP_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPP_Graphics3D_Proxy::OnMsgContextLost(PP_Instance instance) { if (ppp_graphics_3d_impl_) - ppp_graphics_3d_impl_->Graphics3DContextLost(instance); + CallWhileUnlocked(ppp_graphics_3d_impl_->Graphics3DContextLost, instance); } } // namespace proxy diff --git a/ppapi/proxy/ppp_input_event_proxy.cc b/ppapi/proxy/ppp_input_event_proxy.cc index be58b3ce..e49296f 100644 --- a/ppapi/proxy/ppp_input_event_proxy.cc +++ b/ppapi/proxy/ppp_input_event_proxy.cc @@ -98,7 +98,9 @@ void PPP_InputEvent_Proxy::OnMsgHandleInputEvent(PP_Instance instance, const InputEventData& data) { scoped_refptr<PPB_InputEvent_Shared> resource(new PPB_InputEvent_Shared( OBJECT_IS_PROXY, instance, data)); - ppp_input_event_impl_->HandleInputEvent(instance, resource->pp_resource()); + CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent, + instance, + resource->pp_resource()); } void PPP_InputEvent_Proxy::OnMsgHandleFilteredInputEvent( @@ -107,8 +109,9 @@ void PPP_InputEvent_Proxy::OnMsgHandleFilteredInputEvent( PP_Bool* result) { scoped_refptr<PPB_InputEvent_Shared> resource(new PPB_InputEvent_Shared( OBJECT_IS_PROXY, instance, data)); - *result = ppp_input_event_impl_->HandleInputEvent(instance, - resource->pp_resource()); + *result = CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent, + instance, + resource->pp_resource()); } } // namespace proxy diff --git a/ppapi/proxy/ppp_instance_private_proxy.cc b/ppapi/proxy/ppp_instance_private_proxy.cc index 75e9d60..678d30b 100644 --- a/ppapi/proxy/ppp_instance_private_proxy.cc +++ b/ppapi/proxy/ppp_instance_private_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +12,7 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { namespace proxy { @@ -74,7 +75,8 @@ void PPP_Instance_Private_Proxy::OnMsgGetInstanceObject( PP_Instance instance, SerializedVarReturnValue result) { result.Return(dispatcher(), - ppp_instance_private_impl_->GetInstanceObject(instance)); + CallWhileUnlocked(ppp_instance_private_impl_->GetInstanceObject, + instance)); } } // namespace proxy diff --git a/ppapi/proxy/ppp_instance_private_proxy_unittest.cc b/ppapi/proxy/ppp_instance_private_proxy_unittest.cc index 6b87f12..957a3a7 100644 --- a/ppapi/proxy/ppp_instance_private_proxy_unittest.cc +++ b/ppapi/proxy/ppp_instance_private_proxy_unittest.cc @@ -58,7 +58,7 @@ PP_Var GetInstanceObject(PP_Instance /*instance*/) { // The 1 ref we got from CreateObject will be passed to the host. We want to // have a ref of our own. printf("GetInstanceObject called\n"); - PpapiGlobals::Get()->GetVarTracker()->AddRefVar(instance_obj); + plugin_var_deprecated_if()->AddRef(instance_obj); return instance_obj; } diff --git a/ppapi/proxy/ppp_messaging_proxy.cc b/ppapi/proxy/ppp_messaging_proxy.cc index 7a45fd30..16e639e 100644 --- a/ppapi/proxy/ppp_messaging_proxy.cc +++ b/ppapi/proxy/ppp_messaging_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,6 +13,7 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/var_tracker.h" namespace ppapi { @@ -85,7 +86,9 @@ void PPP_Messaging_Proxy::OnMsgHandleMessage( // SerializedVarReceiveInput will decrement the reference count, but we want // to give the recipient a reference. PpapiGlobals::Get()->GetVarTracker()->AddRefVar(received_var); - ppp_messaging_impl_->HandleMessage(instance, received_var); + CallWhileUnlocked(ppp_messaging_impl_->HandleMessage, + instance, + received_var); } } // namespace proxy diff --git a/ppapi/proxy/ppp_mouse_lock_proxy.cc b/ppapi/proxy/ppp_mouse_lock_proxy.cc index 37ca35b..10aa47f 100644 --- a/ppapi/proxy/ppp_mouse_lock_proxy.cc +++ b/ppapi/proxy/ppp_mouse_lock_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,6 +7,7 @@ #include "ppapi/c/ppp_mouse_lock.h" #include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { namespace proxy { @@ -71,7 +72,7 @@ bool PPP_MouseLock_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPP_MouseLock_Proxy::OnMsgMouseLockLost(PP_Instance instance) { if (ppp_mouse_lock_impl_) - ppp_mouse_lock_impl_->MouseLockLost(instance); + CallWhileUnlocked(ppp_mouse_lock_impl_->MouseLockLost, instance); } } // namespace proxy diff --git a/ppapi/proxy/ppp_video_decoder_proxy.cc b/ppapi/proxy/ppp_video_decoder_proxy.cc index 6330b11..1ebf20a 100644 --- a/ppapi/proxy/ppp_video_decoder_proxy.cc +++ b/ppapi/proxy/ppp_video_decoder_proxy.cc @@ -122,32 +122,41 @@ void PPP_VideoDecoder_Proxy::OnMsgProvidePictureBuffers( const PP_Size& dimensions) { PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> PluginResourceForHostResource(decoder); - ppp_video_decoder_impl_->ProvidePictureBuffers( - decoder.instance(), plugin_decoder, req_num_of_bufs, &dimensions); + CallWhileUnlocked(ppp_video_decoder_impl_->ProvidePictureBuffers, + decoder.instance(), + plugin_decoder, + req_num_of_bufs, + &dimensions); } void PPP_VideoDecoder_Proxy::OnMsgDismissPictureBuffer( const HostResource& decoder, int32_t picture_id) { PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> PluginResourceForHostResource(decoder); - ppp_video_decoder_impl_->DismissPictureBuffer( - decoder.instance(), plugin_decoder, picture_id); + CallWhileUnlocked(ppp_video_decoder_impl_->DismissPictureBuffer, + decoder.instance(), + plugin_decoder, + picture_id); } void PPP_VideoDecoder_Proxy::OnMsgPictureReady( const HostResource& decoder, const PP_Picture_Dev& picture) { PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> PluginResourceForHostResource(decoder); - ppp_video_decoder_impl_->PictureReady( - decoder.instance(), plugin_decoder, &picture); + CallWhileUnlocked(ppp_video_decoder_impl_->PictureReady, + decoder.instance(), + plugin_decoder, + &picture); } void PPP_VideoDecoder_Proxy::OnMsgNotifyError( const HostResource& decoder, PP_VideoDecodeError_Dev error) { PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> PluginResourceForHostResource(decoder); - ppp_video_decoder_impl_->NotifyError( - decoder.instance(), plugin_decoder, error); + CallWhileUnlocked(ppp_video_decoder_impl_->NotifyError, + decoder.instance(), + plugin_decoder, + error); } } // namespace proxy diff --git a/ppapi/proxy/serialized_var_unittest.cc b/ppapi/proxy/serialized_var_unittest.cc index e7c690c..f5c1dde 100644 --- a/ppapi/proxy/serialized_var_unittest.cc +++ b/ppapi/proxy/serialized_var_unittest.cc @@ -5,6 +5,7 @@ #include "ppapi/proxy/ppapi_proxy_test.h" #include "ppapi/proxy/serialized_var.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { namespace proxy { @@ -28,6 +29,7 @@ class SerializedVarTest : public PluginProxyTest { // Tests output arguments in the plugin. This is when the host calls into the // plugin and the plugin returns something via an out param, like an exception. TEST_F(SerializedVarTest, PluginSerializedVarInOutParam) { + ProxyAutoLock lock; PP_Var host_object = MakeObjectVar(0x31337); PP_Var plugin_object; @@ -77,6 +79,7 @@ TEST_F(SerializedVarTest, PluginSerializedVarInOutParam) { // Tests output strings in the plugin. This is when the host calls into the // plugin with a string and the plugin returns it via an out param. TEST_F(SerializedVarTest, PluginSerializedStringVarInOutParam) { + ProxyAutoLock lock; PP_Var plugin_string; const std::string kTestString("elite"); { @@ -118,6 +121,7 @@ TEST_F(SerializedVarTest, PluginSerializedStringVarInOutParam) { // Tests receiving an argument and passing it back to the browser as an output // parameter. TEST_F(SerializedVarTest, PluginSerializedVarOutParam) { + ProxyAutoLock lock; PP_Var host_object = MakeObjectVar(0x31337); // Start tracking this object in the plugin. @@ -157,6 +161,7 @@ TEST_F(SerializedVarTest, PluginSerializedVarOutParam) { // Tests the case that the plugin receives the same var twice as an input // parameter (not passing ownership). TEST_F(SerializedVarTest, PluginReceiveInput) { + ProxyAutoLock lock; PP_Var host_object = MakeObjectVar(0x31337); PP_Var plugin_object; @@ -197,6 +202,7 @@ TEST_F(SerializedVarTest, PluginReceiveInput) { // Tests the case that the plugin receives the same vars twice as an input // parameter (not passing ownership) within a vector. TEST_F(SerializedVarTest, PluginVectorReceiveInput) { + ProxyAutoLock lock; PP_Var host_object = MakeObjectVar(0x31337); PP_Var* plugin_objects; @@ -263,6 +269,7 @@ TEST_F(SerializedVarTest, PluginVectorReceiveInput) { // Tests the plugin receiving a var as a return value from the browser // two different times (passing ownership). TEST_F(SerializedVarTest, PluginReceiveReturn) { + ProxyAutoLock lock; PP_Var host_object = MakeObjectVar(0x31337); PP_Var plugin_object; @@ -306,6 +313,7 @@ TEST_F(SerializedVarTest, PluginReceiveReturn) { // Returns a value from the browser to the plugin, then return that one ref // back to the browser. TEST_F(SerializedVarTest, PluginReturnValue) { + ProxyAutoLock lock; PP_Var host_object = MakeObjectVar(0x31337); PP_Var plugin_object; diff --git a/ppapi/shared_impl/ppp_instance_combined.cc b/ppapi/shared_impl/ppp_instance_combined.cc index d27c2a0..e5b7998 100644 --- a/ppapi/shared_impl/ppp_instance_combined.cc +++ b/ppapi/shared_impl/ppp_instance_combined.cc @@ -1,8 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ppapi/shared_impl/ppp_instance_combined.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { @@ -26,31 +27,36 @@ PP_Bool PPP_Instance_Combined::DidCreate(PP_Instance instance, uint32_t argc, const char* argn[], const char* argv[]) { - return instance_1_1_.DidCreate(instance, argc, argn, argv); + return CallWhileUnlocked(instance_1_1_.DidCreate, instance, argc, argn, argv); } void PPP_Instance_Combined::DidDestroy(PP_Instance instance) { - return instance_1_1_.DidDestroy(instance); + return CallWhileUnlocked(instance_1_1_.DidDestroy, instance); } void PPP_Instance_Combined::DidChangeView(PP_Instance instance, PP_Resource view_changed_resource, const struct PP_Rect* position, const struct PP_Rect* clip) { - if (instance_1_1_.DidChangeView) - instance_1_1_.DidChangeView(instance, view_changed_resource); - else - did_change_view_1_0_(instance, position, clip); + if (instance_1_1_.DidChangeView) { + CallWhileUnlocked(instance_1_1_.DidChangeView, + instance, + view_changed_resource); + } else { + CallWhileUnlocked(did_change_view_1_0_, instance, position, clip); + } } void PPP_Instance_Combined::DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { - instance_1_1_.DidChangeFocus(instance, has_focus); + CallWhileUnlocked(instance_1_1_.DidChangeFocus, instance, has_focus); } PP_Bool PPP_Instance_Combined::HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { - return instance_1_1_.HandleDocumentLoad(instance, url_loader); + return CallWhileUnlocked(instance_1_1_.HandleDocumentLoad, + instance, + url_loader); } } // namespace ppapi diff --git a/ppapi/shared_impl/proxy_lock.cc b/ppapi/shared_impl/proxy_lock.cc index 226c51f..7ef652b 100644 --- a/ppapi/shared_impl/proxy_lock.cc +++ b/ppapi/shared_impl/proxy_lock.cc @@ -23,4 +23,9 @@ void ProxyLock::Release() { lock->Release(); } +void CallWhileLocked(const base::Closure& closure) { + ProxyAutoLock lock; + closure.Run(); +} + } // namespace ppapi diff --git a/ppapi/shared_impl/proxy_lock.h b/ppapi/shared_impl/proxy_lock.h index c5571f3..ccb7324 100644 --- a/ppapi/shared_impl/proxy_lock.h +++ b/ppapi/shared_impl/proxy_lock.h @@ -6,6 +6,8 @@ #define PPAPI_SHARED_IMPL_PROXY_LOCK_H_ #include "base/basictypes.h" +#include "base/bind.h" +#include "base/callback.h" #include "ppapi/shared_impl/ppapi_shared_export.h" @@ -34,6 +36,7 @@ class PPAPI_SHARED_EXPORT ProxyLock { // Relinquish the proxy lock. If the lock has not been set, this does nothing. static void Release(); + private: DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock); }; @@ -68,6 +71,78 @@ class ProxyAutoUnlock { DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock); }; +// A set of function template overloads for invoking a function pointer while +// the ProxyLock is unlocked. This assumes that the luck is held. +// CallWhileUnlocked unlocks the ProxyLock just before invoking the given +// function. The lock is immediately re-acquired when the invoked function +// function returns. CallWhileUnlocked returns whatever the given function +// returned. +// +// Example usage: +// *result = CallWhileUnlocked(ppp_input_event_impl_->HandleInputEvent, +// instance, +// resource->pp_resource()); +template <class ReturnType> +ReturnType CallWhileUnlocked(ReturnType (*function)()) { + ProxyAutoUnlock unlock; + return function(); +} +template <class ReturnType, class P1> +ReturnType CallWhileUnlocked(ReturnType (*function)(P1), const P1& p1) { + ProxyAutoUnlock unlock; + return function(p1); +} +template <class ReturnType, class P1, class P2> +ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2), + const P1& p1, + const P2& p2) { + ProxyAutoUnlock unlock; + return function(p1, p2); +} +template <class ReturnType, class P1, class P2, class P3> +ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2, P3), + const P1& p1, + const P2& p2, + const P3& p3) { + ProxyAutoUnlock unlock; + return function(p1, p2, p3); +} +template <class ReturnType, class P1, class P2, class P3, class P4> +ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2, P3, P4), + const P1& p1, + const P2& p2, + const P3& p3, + const P4& p4) { + ProxyAutoUnlock unlock; + return function(p1, p2, p3, p4); +} +template <class ReturnType, class P1, class P2, class P3, class P4, class P5> +ReturnType CallWhileUnlocked(ReturnType (*function)(P1, P2, P3, P4, P5), + const P1& p1, + const P2& p2, + const P3& p3, + const P4& p4, + const P5& p5) { + ProxyAutoUnlock unlock; + return function(p1, p2, p3, p4, p5); +} + +// CallWhileLocked locks the ProxyLock and runs the given closure immediately. +// The lock is released when CallWhileLocked returns. This function assumes the +// lock is not held. This is mostly for use in RunWhileLocked; see below. +void CallWhileLocked(const base::Closure& closure); + +// RunWhileLocked binds the given closure with CallWhileLocked and returns the +// new Closure. This is for cases where you want to run a task, but you want to +// ensure that the ProxyLock is acquired for the duration of the task. +// Example usage: +// GetMainThreadMessageLoop()->PostDelayedTask( +// FROM_HERE, +// RunWhileLocked(base::Bind(&CallbackWrapper, callback, result)), +// delay_in_ms); +inline base::Closure RunWhileLocked(const base::Closure& closure) { + return base::Bind(CallWhileLocked, closure); +} } // namespace ppapi diff --git a/ppapi/shared_impl/tracked_callback.cc b/ppapi/shared_impl/tracked_callback.cc index a49f4ff..f97acfd 100644 --- a/ppapi/shared_impl/tracked_callback.cc +++ b/ppapi/shared_impl/tracked_callback.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +12,7 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/shared_impl/callback_tracker.h" #include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/resource.h" namespace ppapi { @@ -49,8 +50,8 @@ void TrackedCallback::PostAbort() { if (!abort_impl_factory_.HasWeakPtrs()) { MessageLoop::current()->PostTask( FROM_HERE, - base::Bind(&TrackedCallback::Abort, - abort_impl_factory_.GetWeakPtr())); + RunWhileLocked(base::Bind(&TrackedCallback::Abort, + abort_impl_factory_.GetWeakPtr()))); } } } @@ -69,7 +70,7 @@ void TrackedCallback::Run(int32_t result) { // Do this before running the callback in case of reentrancy (which // shouldn't happen, but avoid strange failures). MarkAsCompleted(); - PP_RunCompletionCallback(&callback, result); + CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); } } diff --git a/ppapi/thunk/enter.cc b/ppapi/thunk/enter.cc index 42ff670..d8d4291 100644 --- a/ppapi/thunk/enter.cc +++ b/ppapi/thunk/enter.cc @@ -40,8 +40,8 @@ EnterBase::~EnterBase() { if (callback_.func) { // All async completions should have cleared the callback in SetResult(). DCHECK(retval_ != PP_OK_COMPLETIONPENDING && retval_ != PP_OK); - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( - callback_.func, callback_.user_data, retval_)); + MessageLoop::current()->PostTask(FROM_HERE, RunWhileLocked(base::Bind( + callback_.func, callback_.user_data, retval_))); } } @@ -57,8 +57,8 @@ int32_t EnterBase::SetResult(int32_t result) { // This is a required callback, asynchronously issue it. // TODO(brettw) make this work on different threads, etc. - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( - callback_.func, callback_.user_data, result)); + MessageLoop::current()->PostTask(FROM_HERE, RunWhileLocked(base::Bind( + callback_.func, callback_.user_data, result))); // Now that the callback will be issued in the future, we should return // "pending" to the caller, and not issue the callback again. @@ -85,9 +85,9 @@ void EnterBase::SetStateForResourceError(PP_Resource pp_resource, if (callback_.func) { // Required callback, issue the async completion. - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( + MessageLoop::current()->PostTask(FROM_HERE, RunWhileLocked(base::Bind( callback_.func, callback_.user_data, - static_cast<int32_t>(PP_ERROR_BADRESOURCE))); + static_cast<int32_t>(PP_ERROR_BADRESOURCE)))); callback_ = PP_BlockUntilComplete(); retval_ = PP_OK_COMPLETIONPENDING; } else { @@ -121,9 +121,9 @@ void EnterBase::SetStateForFunctionError(PP_Instance pp_instance, if (callback_.func) { // Required callback, issue the async completion. - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( + MessageLoop::current()->PostTask(FROM_HERE, RunWhileLocked(base::Bind( callback_.func, callback_.user_data, - static_cast<int32_t>(PP_ERROR_BADARGUMENT))); + static_cast<int32_t>(PP_ERROR_BADARGUMENT)))); callback_ = PP_BlockUntilComplete(); retval_ = PP_OK_COMPLETIONPENDING; } else { @@ -145,7 +145,7 @@ void EnterBase::SetStateForFunctionError(PP_Instance pp_instance, } // namespace subtle EnterResourceCreation::EnterResourceCreation(PP_Instance instance) - : EnterFunctionNoLock<ResourceCreationAPI>(instance, true) { + : EnterFunction<ResourceCreationAPI>(instance, true) { } EnterResourceCreation::~EnterResourceCreation() { diff --git a/ppapi/thunk/enter.h b/ppapi/thunk/enter.h index 3b82a96..4172ce0 100644 --- a/ppapi/thunk/enter.h +++ b/ppapi/thunk/enter.h @@ -245,7 +245,7 @@ class EnterResourceNoLock : public EnterResource<ResourceT, false> { // class so we have this helper function to save template instantiations and // typing. class PPAPI_THUNK_EXPORT EnterResourceCreation - : public EnterFunctionNoLock<ResourceCreationAPI> { + : public EnterFunction<ResourceCreationAPI> { public: EnterResourceCreation(PP_Instance instance); ~EnterResourceCreation(); |