diff options
25 files changed, 400 insertions, 164 deletions
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index f0db156..5ed1873 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc @@ -36,7 +36,9 @@ #include "ppapi/c/ppp.h" #include "ppapi/proxy/interface_list.h" #include "ppapi/proxy/plugin_globals.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_reply_thread_registrar.h" #include "third_party/WebKit/public/web/WebKit.h" #include "ui/base/ui_base_switches.h" @@ -72,6 +74,12 @@ PpapiThread::PpapiThread(const CommandLine& command_line, bool is_broker) webkit_platform_support_.reset(new PpapiWebKitPlatformSupportImpl); blink::initialize(webkit_platform_support_.get()); + + if (!is_broker_) { + channel()->AddFilter( + new ppapi::proxy::PluginMessageFilter( + NULL, globals->resource_reply_thread_registrar())); + } } PpapiThread::~PpapiThread() { @@ -104,7 +112,6 @@ bool PpapiThread::OnControlMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnSetNetworkState) IPC_MESSAGE_HANDLER(PpapiMsg_Crash, OnCrash) IPC_MESSAGE_HANDLER(PpapiMsg_Hang, OnHang) - IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnResourceReply) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -355,13 +362,6 @@ void PpapiThread::OnCreateChannel(base::ProcessId renderer_pid, Send(new PpapiHostMsg_ChannelCreated(channel_handle)); } -void PpapiThread::OnResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg) { - ppapi::proxy::PluginDispatcher::DispatchResourceReply(reply_params, - nested_msg); -} - void PpapiThread::OnSetNetworkState(bool online) { // Note the browser-process side shouldn't send us these messages in the // first unless the plugin has dev permissions, so we don't need to check diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h index 8a06c4d..17deb5e 100644 --- a/content/ppapi_plugin/ppapi_thread.h +++ b/content/ppapi_plugin/ppapi_thread.h @@ -97,9 +97,6 @@ class PpapiThread : public ChildThread, void OnCreateChannel(base::ProcessId renderer_pid, int renderer_child_id, bool incognito); - void OnResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg); void OnSetNetworkState(bool online); void OnCrash(); void OnHang(); diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 9246e2a..35186c8 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -178,6 +178,8 @@ 'proxy/proxy_object_var.h', 'proxy/resource_creation_proxy.cc', 'proxy/resource_creation_proxy.h', + 'proxy/resource_reply_thread_registrar.cc', + 'proxy/resource_reply_thread_registrar.h', 'proxy/talk_resource.cc', 'proxy/talk_resource.h', 'proxy/tcp_server_socket_private_resource.cc', diff --git a/ppapi/proxy/device_enumeration_resource_helper_unittest.cc b/ppapi/proxy/device_enumeration_resource_helper_unittest.cc index 56c09d7..bbf7052 100644 --- a/ppapi/proxy/device_enumeration_resource_helper_unittest.cc +++ b/ppapi/proxy/device_enumeration_resource_helper_unittest.cc @@ -7,6 +7,7 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/proxy/connection.h" #include "ppapi/proxy/device_enumeration_resource_helper.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/plugin_var_tracker.h" @@ -258,10 +259,9 @@ TEST_F(DeviceEnumerationResourceHelperTest, EnumerateDevices) { { ProxyAutoUnlock unlock; - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(data)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(data)); } EXPECT_TRUE(callback.called()); EXPECT_EQ(PP_OK, callback.result()); @@ -304,11 +304,10 @@ TEST_F(DeviceEnumerationResourceHelperTest, MonitorDeviceChange) { { ProxyAutoUnlock unlock; // Synthesize a response with no device. - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( - callback_id, data)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( + callback_id, data)); } EXPECT_TRUE(helper.called() && helper.same_as_expected()); @@ -327,11 +326,10 @@ TEST_F(DeviceEnumerationResourceHelperTest, MonitorDeviceChange) { { ProxyAutoUnlock unlock; // Synthesize a response with some devices. - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( - callback_id, data)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( + callback_id, data)); } EXPECT_TRUE(helper.called() && helper.same_as_expected()); @@ -357,11 +355,10 @@ TEST_F(DeviceEnumerationResourceHelperTest, MonitorDeviceChange) { { ProxyAutoUnlock unlock; // |helper2| should receive the result while |helper| shouldn't. - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( - callback_id2, data)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( + callback_id2, data)); } EXPECT_TRUE(helper2.called() && helper2.same_as_expected()); EXPECT_FALSE(helper.called()); @@ -372,11 +369,10 @@ TEST_F(DeviceEnumerationResourceHelperTest, MonitorDeviceChange) { ProxyAutoUnlock unlock; // Even if a message with |callback_id| arrives. |helper| shouldn't receive // the result. - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( - callback_id, data)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( + callback_id, data)); } EXPECT_FALSE(helper2.called()); EXPECT_FALSE(helper.called()); @@ -396,11 +392,10 @@ TEST_F(DeviceEnumerationResourceHelperTest, MonitorDeviceChange) { { ProxyAutoUnlock unlock; // |helper2| shouldn't receive any result any more. - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( - callback_id2, data)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( + callback_id2, data)); } EXPECT_FALSE(helper2.called()); } diff --git a/ppapi/proxy/file_chooser_resource_unittest.cc b/ppapi/proxy/file_chooser_resource_unittest.cc index 4ba5bd9..a97b9c9 100644 --- a/ppapi/proxy/file_chooser_resource_unittest.cc +++ b/ppapi/proxy/file_chooser_resource_unittest.cc @@ -8,6 +8,7 @@ #include "ppapi/c/ppb_file_ref.h" #include "ppapi/proxy/file_chooser_resource.h" #include "ppapi/proxy/locking_resource_releaser.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppapi_proxy_test.h" #include "ppapi/shared_impl/proxy_lock.h" @@ -101,9 +102,8 @@ TEST_F(FileChooserResourceTest, Show) { create_info.browser_pending_host_resource_id = 12; create_info.renderer_pending_host_resource_id = 15; create_info_array.push_back(create_info); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply(reply_params, - PpapiPluginMsg_FileChooser_ShowReply(create_info_array)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, PpapiPluginMsg_FileChooser_ShowReply(create_info_array)); // Should have populated our vector. ASSERT_EQ(1u, dest.size()); diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index 4dc3a45..6cd0ab4 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -29,7 +29,7 @@ #include "ppapi/proxy/ppb_instance_proxy.h" #include "ppapi/proxy/ppp_class_proxy.h" #include "ppapi/proxy/resource_creation_proxy.h" -#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/proxy/resource_reply_thread_registrar.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/shared_impl/resource.h" @@ -173,7 +173,9 @@ bool PluginDispatcher::InitPluginWithChannel( // The message filter will intercept and process certain messages directly // on the I/O thread. channel()->AddFilter( - new PluginMessageFilter(delegate->GetGloballySeenInstanceIDSet())); + new PluginMessageFilter( + delegate->GetGloballySeenInstanceIDSet(), + PluginGlobals::Get()->resource_reply_thread_registrar())); return true; } @@ -226,7 +228,6 @@ bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { // Handle some plugin-specific control messages. bool handled = true; IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg) - IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply) IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface) IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences) IPC_MESSAGE_UNHANDLED(handled = false); @@ -287,16 +288,6 @@ thunk::ResourceCreationAPI* PluginDispatcher::GetResourceCreationAPI() { GetInterfaceProxy(API_ID_RESOURCE_CREATION)); } -// static -void PluginDispatcher::DispatchResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_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; - LockedDispatchResourceReply(reply_params, nested_msg); -} - void PluginDispatcher::ForceFreeAllInstances() { if (!g_instance_to_dispatcher) return; @@ -315,12 +306,6 @@ void PluginDispatcher::ForceFreeAllInstances() { } } -void PluginDispatcher::OnMsgResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg) { - LockedDispatchResourceReply(reply_params, nested_msg); -} - void PluginDispatcher::OnMsgSupportsInterface( const std::string& interface_name, bool* result) { @@ -349,20 +334,5 @@ void PluginDispatcher::OnMsgSetPreferences(const Preferences& prefs) { } } -// static -void PluginDispatcher::LockedDispatchResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg) { - Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource( - reply_params.pp_resource()); - if (!resource) { - DLOG_IF(INFO, reply_params.sequence() != 0) - << "Pepper resource reply message received but the resource doesn't " - "exist (probably has been destroyed)."; - return; - } - resource->OnReplyReceived(reply_params, nested_msg); -} - } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h index 3a9e733..5176eba 100644 --- a/ppapi/proxy/plugin_dispatcher.h +++ b/ppapi/proxy/plugin_dispatcher.h @@ -40,8 +40,6 @@ class ResourceCreationAPI; namespace proxy { -class ResourceMessageReplyParams; - // Used to keep track of per-instance data. struct InstanceData { InstanceData(); @@ -163,13 +161,6 @@ class PPAPI_PROXY_EXPORT PluginDispatcher uint32 plugin_dispatcher_id() const { return plugin_dispatcher_id_; } bool incognito() const { return incognito_; } - // Dispatches the given resource message to the appropriate resource in the - // plugin process. This should be wired to the various channels that messages - // come in from various other processes. - static void DispatchResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg); - private: friend class PluginDispatcherTest; @@ -178,17 +169,9 @@ class PPAPI_PROXY_EXPORT PluginDispatcher void ForceFreeAllInstances(); // IPC message handlers. - void OnMsgResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg); void OnMsgSupportsInterface(const std::string& interface_name, bool* result); void OnMsgSetPreferences(const Preferences& prefs); - // Internal backed for DispatchResourceReply. - static void LockedDispatchResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg); - virtual bool SendMessage(IPC::Message* msg); PluginDelegate* plugin_delegate_; diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc index fa5530e..59b5191 100644 --- a/ppapi/proxy/plugin_globals.cc +++ b/ppapi/proxy/plugin_globals.cc @@ -11,6 +11,7 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_proxy_delegate.h" #include "ppapi/proxy/ppb_message_loop_proxy.h" +#include "ppapi/proxy/resource_reply_thread_registrar.h" #include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/thunk/enter.h" @@ -51,7 +52,9 @@ PluginGlobals* PluginGlobals::plugin_globals_ = NULL; PluginGlobals::PluginGlobals() : ppapi::PpapiGlobals(), plugin_proxy_delegate_(NULL), - callback_tracker_(new CallbackTracker) { + callback_tracker_(new CallbackTracker), + resource_reply_thread_registrar_( + new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) { DCHECK(!plugin_globals_); plugin_globals_ = this; @@ -66,7 +69,9 @@ PluginGlobals::PluginGlobals() PluginGlobals::PluginGlobals(PerThreadForTest per_thread_for_test) : ppapi::PpapiGlobals(per_thread_for_test), plugin_proxy_delegate_(NULL), - callback_tracker_(new CallbackTracker) { + callback_tracker_(new CallbackTracker), + resource_reply_thread_registrar_( + new ResourceReplyThreadRegistrar(GetMainThreadMessageLoop())) { DCHECK(!plugin_globals_); } diff --git a/ppapi/proxy/plugin_globals.h b/ppapi/proxy/plugin_globals.h index bc55245..029e2d2 100644 --- a/ppapi/proxy/plugin_globals.h +++ b/ppapi/proxy/plugin_globals.h @@ -34,6 +34,7 @@ namespace proxy { class MessageLoopResource; class PluginProxyDelegate; +class ResourceReplyThreadRegistrar; class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { public: @@ -128,6 +129,10 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { // The embedder should call this function when the command line is known. void set_command_line(const std::string& c) { command_line_ = c; } + ResourceReplyThreadRegistrar* resource_reply_thread_registrar() { + return resource_reply_thread_registrar_.get(); + } + private: class BrowserSender; @@ -160,6 +165,8 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { // lazily, since it might not be needed. scoped_ptr<base::Thread> file_thread_; + scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_; + DISALLOW_COPY_AND_ASSIGN(PluginGlobals); }; diff --git a/ppapi/proxy/plugin_main_nacl.cc b/ppapi/proxy/plugin_main_nacl.cc index f050778..bced108 100644 --- a/ppapi/proxy/plugin_main_nacl.cc +++ b/ppapi/proxy/plugin_main_nacl.cc @@ -26,7 +26,9 @@ #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_globals.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/plugin_proxy_delegate.h" +#include "ppapi/proxy/resource_reply_thread_registrar.h" #include "ppapi/shared_impl/ppb_audio_shared.h" #if defined(IPC_MESSAGE_LOG_ENABLED) @@ -91,9 +93,6 @@ class PpapiDispatcher : public ProxyChannel, void OnMsgCreateNaClChannel(int renderer_id, const ppapi::PpapiNaClChannelArgs& args, SerializedHandle handle); - void OnMsgResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg); void OnPluginDispatcherMessageReceived(const IPC::Message& msg); std::set<PP_Instance> instances_; @@ -113,6 +112,8 @@ PpapiDispatcher::PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop) // NaCl sandbox. InitWithChannel(this, base::kNullProcessId, channel_handle, false); // Channel is server. + channel()->AddFilter(new ppapi::proxy::PluginMessageFilter( + NULL, PluginGlobals::Get()->resource_reply_thread_registrar())); channel()->AddFilter( new tracing::ChildTraceMessageFilter(message_loop_.get())); } @@ -186,7 +187,6 @@ PP_Resource PpapiDispatcher::CreateBrowserFont( bool PpapiDispatcher::OnMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(PpapiDispatcher, msg) IPC_MESSAGE_HANDLER(PpapiMsg_CreateNaClChannel, OnMsgCreateNaClChannel) - IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply) // All other messages are simply forwarded to a PluginDispatcher. IPC_MESSAGE_UNHANDLED(OnPluginDispatcherMessageReceived(msg)) IPC_END_MESSAGE_MAP() @@ -235,13 +235,6 @@ void PpapiDispatcher::OnMsgCreateNaClChannel( // lifetime of the attached channel. } -void PpapiDispatcher::OnMsgResourceReply( - const ppapi::proxy::ResourceMessageReplyParams& reply_params, - const IPC::Message& nested_msg) { - ppapi::proxy::PluginDispatcher::DispatchResourceReply(reply_params, - nested_msg); -} - void PpapiDispatcher::OnPluginDispatcherMessageReceived( const IPC::Message& msg) { // The first parameter should be a plugin dispatcher ID. diff --git a/ppapi/proxy/plugin_message_filter.cc b/ppapi/proxy/plugin_message_filter.cc index 9f178f1..1a62d21 100644 --- a/ppapi/proxy/plugin_message_filter.cc +++ b/ppapi/proxy/plugin_message_filter.cc @@ -4,14 +4,24 @@ #include "ppapi/proxy/plugin_message_filter.h" +#include "base/bind.h" +#include "base/logging.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/proxy/resource_reply_thread_registrar.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" namespace ppapi { namespace proxy { PluginMessageFilter::PluginMessageFilter( - std::set<PP_Instance>* seen_instance_ids) + std::set<PP_Instance>* seen_instance_ids, + scoped_refptr<ResourceReplyThreadRegistrar> registrar) : seen_instance_ids_(seen_instance_ids), + resource_reply_thread_registrar_(registrar), channel_(NULL) { } @@ -30,6 +40,7 @@ bool PluginMessageFilter::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PluginMessageFilter, message) IPC_MESSAGE_HANDLER(PpapiMsg_ReserveInstanceId, OnMsgReserveInstanceId) + IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -42,8 +53,18 @@ bool PluginMessageFilter::Send(IPC::Message* msg) { return false; } +// static +void PluginMessageFilter::DispatchResourceReplyForTest( + const ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg) { + DispatchResourceReply(reply_params, nested_msg); +} + void PluginMessageFilter::OnMsgReserveInstanceId(PP_Instance instance, bool* usable) { + // If |seen_instance_ids_| is set to NULL, we are not supposed to see this + // message. + CHECK(seen_instance_ids_); // See the message definition for how this works. if (seen_instance_ids_->find(instance) != seen_instance_ids_->end()) { // Instance ID already seen, reject it. @@ -57,5 +78,33 @@ void PluginMessageFilter::OnMsgReserveInstanceId(PP_Instance instance, *usable = true; } +void PluginMessageFilter::OnMsgResourceReply( + const ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg) { + scoped_refptr<base::MessageLoopProxy> target = + resource_reply_thread_registrar_->GetTargetThreadAndUnregister( + reply_params.pp_resource(), reply_params.sequence()); + + target->PostTask( + FROM_HERE, + base::Bind(&DispatchResourceReply, reply_params, nested_msg)); +} + +// static +void PluginMessageFilter::DispatchResourceReply( + const ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg) { + ProxyAutoLock lock; + Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource( + reply_params.pp_resource()); + if (!resource) { + DVLOG_IF(1, reply_params.sequence() != 0) + << "Pepper resource reply message received but the resource doesn't " + "exist (probably has been destroyed)."; + return; + } + resource->OnReplyReceived(reply_params, nested_msg); +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/plugin_message_filter.h b/ppapi/proxy/plugin_message_filter.h index 5701a96..6469007 100644 --- a/ppapi/proxy/plugin_message_filter.h +++ b/ppapi/proxy/plugin_message_filter.h @@ -8,26 +8,37 @@ #include <set> #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_sender.h" #include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/ppapi_proxy_export.h" namespace ppapi { namespace proxy { +class ResourceMessageReplyParams; +class ResourceReplyThreadRegistrar; + // Listens for messages on the I/O thread of the plugin and handles some of // them to avoid needing to block on the plugin. // // There is one instance of this class for each renderer channel (same as for // the PluginDispatchers). -class PluginMessageFilter : public IPC::ChannelProxy::MessageFilter, - public IPC::Sender { +class PPAPI_PROXY_EXPORT PluginMessageFilter + : public IPC::ChannelProxy::MessageFilter, + public IPC::Sender { public: - // The input is a pointer to a set that will be used to uniquify PP_Instances - // across all renderer channels. The same pointer should be passed to each - // MessageFilter to ensure uniqueness, and the value should outlive this - // class. - PluginMessageFilter(std::set<PP_Instance>* seen_instance_ids); + // |seen_instance_ids| is a pointer to a set that will be used to uniquify + // PP_Instances across all renderer channels. The same pointer should be + // passed to each MessageFilter to ensure uniqueness, and the value should + // outlive this class. It could be NULL if this filter is for a browser + // channel. + // |thread_registrar| is used to look up handling threads for resource + // reply messages. It shouldn't be NULL. + PluginMessageFilter( + std::set<PP_Instance>* seen_instance_ids, + scoped_refptr<ResourceReplyThreadRegistrar> thread_registrar); virtual ~PluginMessageFilter(); // MessageFilter implementation. @@ -38,14 +49,30 @@ class PluginMessageFilter : public IPC::ChannelProxy::MessageFilter, // IPC::Sender implementation. virtual bool Send(IPC::Message* msg) OVERRIDE; + // Simulates an incoming resource reply that is handled on the calling thread. + // For testing only. + static void DispatchResourceReplyForTest( + const ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg); + private: void OnMsgReserveInstanceId(PP_Instance instance, bool* usable); + void OnMsgResourceReply(const ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg); - // All instance IDs every queried by any renderer on this plugin. This is - // used to make sure that new instance IDs are unique. This is a non-owning - // pointer, it will be managed by the later that creates this class. + // Dispatches the given resource reply to the appropriate resource in the + // plugin process. + static void DispatchResourceReply( + const ResourceMessageReplyParams& reply_params, + const IPC::Message& nested_msg); + + // All instance IDs ever queried by any renderer on this plugin. This is used + // to make sure that new instance IDs are unique. This is a non-owning + // pointer. It is managed by PluginDispatcher::PluginDelegate. std::set<PP_Instance>* seen_instance_ids_; + scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_; + // The IPC channel to the renderer. May be NULL if we're not currently // attached as a filter. IPC::Channel* channel_; diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc index 3f4b612..23094fe 100644 --- a/ppapi/proxy/plugin_resource.cc +++ b/ppapi/proxy/plugin_resource.cc @@ -6,7 +6,9 @@ #include <limits> +#include "ppapi/proxy/plugin_globals.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_globals.h" namespace ppapi { namespace proxy { @@ -16,7 +18,10 @@ PluginResource::PluginResource(Connection connection, PP_Instance instance) connection_(connection), next_sequence_number_(1), sent_create_to_browser_(false), - sent_create_to_renderer_(false) { + sent_create_to_renderer_(false), + resource_reply_thread_registrar_( + PpapiGlobals::Get()->IsPluginGlobals() ? + PluginGlobals::Get()->resource_reply_thread_registrar() : NULL) { } PluginResource::~PluginResource() { @@ -28,6 +33,9 @@ PluginResource::~PluginResource() { connection_.renderer_sender->Send( new PpapiHostMsg_ResourceDestroyed(pp_resource())); } + + if (resource_reply_thread_registrar_) + resource_reply_thread_registrar_->Unregister(pp_resource()); } void PluginResource::OnReplyReceived( diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 9448326..e6d3065 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sender.h" #include "ppapi/c/pp_errors.h" @@ -17,8 +18,9 @@ #include "ppapi/proxy/ppapi_message_utils.h" #include "ppapi/proxy/ppapi_proxy_export.h" #include "ppapi/proxy/resource_message_params.h" +#include "ppapi/proxy/resource_reply_thread_registrar.h" #include "ppapi/shared_impl/resource.h" - +#include "ppapi/shared_impl/tracked_callback.h" namespace ppapi { namespace proxy { @@ -99,6 +101,23 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource { const IPC::Message& msg, const CallbackType& callback); + // Comparing with the previous Call() method, this method takes + // |reply_thread_hint| as a hint to determine which thread to handle the reply + // message. + // + // If |reply_thread_hint| is non-blocking, the reply message will be handled + // on the target thread of the callback; otherwise, it will be handled on the + // main thread. + // + // If handling a reply message will cause a TrackedCallback to be run, it is + // recommended to use this version of Call(). It eliminates unnecessary + // thread switching and therefore has better performance. + template<typename ReplyMsgClass, typename CallbackType> + int32_t Call(Destination dest, + const IPC::Message& msg, + const CallbackType& callback, + scoped_refptr<TrackedCallback> reply_thread_hint); + // Calls the browser/renderer with sync messages. Returns the pepper error // code from the call. // |ReplyMsgClass| is the type of the reply message that is expected. If it @@ -159,6 +178,8 @@ class PPAPI_PROXY_EXPORT PluginResource : public Resource { CallbackMap; CallbackMap callbacks_; + scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_; + DISALLOW_COPY_AND_ASSIGN(PluginResource); }; @@ -166,6 +187,15 @@ template<typename ReplyMsgClass, typename CallbackType> int32_t PluginResource::Call(Destination dest, const IPC::Message& msg, const CallbackType& callback) { + return Call<ReplyMsgClass>(dest, msg, callback, NULL); +} + +template<typename ReplyMsgClass, typename CallbackType> +int32_t PluginResource::Call( + Destination dest, + const IPC::Message& msg, + const CallbackType& callback, + scoped_refptr<TrackedCallback> reply_thread_hint) { TRACE_EVENT2("ppapi proxy", "PluginResource::Call", "Class", IPC_MESSAGE_ID_CLASS(msg.type()), "Line", IPC_MESSAGE_ID_LINE(msg.type())); @@ -176,6 +206,11 @@ int32_t PluginResource::Call(Destination dest, new PluginResourceCallback<ReplyMsgClass, CallbackType>(callback)); callbacks_.insert(std::make_pair(params.sequence(), plugin_callback)); params.set_has_callback(); + + if (resource_reply_thread_registrar_) { + resource_reply_thread_registrar_->Register( + pp_resource(), params.sequence(), reply_thread_hint); + } SendResourceCall(dest, params, msg); return params.sequence(); } diff --git a/ppapi/proxy/ppb_message_loop_proxy.cc b/ppapi/proxy/ppb_message_loop_proxy.cc index 7e2cdfa..582ddcb 100644 --- a/ppapi/proxy/ppb_message_loop_proxy.cc +++ b/ppapi/proxy/ppb_message_loop_proxy.cc @@ -189,6 +189,10 @@ void MessageLoopResource::PostClosure( } } +base::MessageLoopProxy* MessageLoopResource::GetMessageLoopProxy() { + return loop_proxy_.get(); +} + // static void MessageLoopResource::ReleaseMessageLoop(void* value) { static_cast<MessageLoopResource*>(value)->DetachFromThread(); diff --git a/ppapi/proxy/ppb_message_loop_proxy.h b/ppapi/proxy/ppb_message_loop_proxy.h index 4e3a933..d8bfc4c 100644 --- a/ppapi/proxy/ppb_message_loop_proxy.h +++ b/ppapi/proxy/ppb_message_loop_proxy.h @@ -63,6 +63,8 @@ class PPAPI_PROXY_EXPORT MessageLoopResource : public MessageLoopShared { const base::Closure& closure, int64 delay_ms) OVERRIDE; + virtual base::MessageLoopProxy* GetMessageLoopProxy() OVERRIDE; + // TLS destructor function. static void ReleaseMessageLoop(void* value); diff --git a/ppapi/proxy/printing_resource_unittest.cc b/ppapi/proxy/printing_resource_unittest.cc index af6c742..6551ba1 100644 --- a/ppapi/proxy/printing_resource_unittest.cc +++ b/ppapi/proxy/printing_resource_unittest.cc @@ -8,6 +8,7 @@ #include "ppapi/c/dev/ppb_printing_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/proxy/locking_resource_releaser.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppapi_proxy_test.h" #include "ppapi/proxy/printing_resource.h" @@ -76,10 +77,10 @@ TEST_F(PrintingResourceTest, GetDefaultPrintSettings) { PP_FALSE, PP_PRINTOUTPUTFORMAT_PDF }; - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply(reply_params, - PpapiPluginMsg_Printing_GetDefaultPrintSettingsReply( - reply_settings)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_Printing_GetDefaultPrintSettingsReply( + reply_settings)); EXPECT_TRUE(PP_RectEqual(reply_settings.printable_area, output_settings.printable_area)); diff --git a/ppapi/proxy/resource_reply_thread_registrar.cc b/ppapi/proxy/resource_reply_thread_registrar.cc new file mode 100644 index 0000000..0c49cf5 --- /dev/null +++ b/ppapi/proxy/resource_reply_thread_registrar.cc @@ -0,0 +1,71 @@ +// Copyright 2013 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/proxy/resource_reply_thread_registrar.h" + +#include "base/logging.h" +#include "base/message_loop/message_loop_proxy.h" +#include "ppapi/shared_impl/proxy_lock.h" +#include "ppapi/shared_impl/tracked_callback.h" + +namespace ppapi { +namespace proxy { + +ResourceReplyThreadRegistrar::ResourceReplyThreadRegistrar( + scoped_refptr<base::MessageLoopProxy> default_thread) + : default_thread_(default_thread) { +} + +ResourceReplyThreadRegistrar::~ResourceReplyThreadRegistrar() { +} + +void ResourceReplyThreadRegistrar::Register( + PP_Resource resource, + int32_t sequence_number, + scoped_refptr<TrackedCallback> reply_thread_hint) { + ProxyLock::AssertAcquiredDebugOnly(); + + // Use the default thread if |reply_thread_hint| is NULL or blocking. + if (!reply_thread_hint || reply_thread_hint->is_blocking()) + return; + + DCHECK(reply_thread_hint->target_loop()); + scoped_refptr<base::MessageLoopProxy> reply_thread( + reply_thread_hint->target_loop()->GetMessageLoopProxy()); + { + base::AutoLock auto_lock(lock_); + + if (reply_thread == default_thread_) + return; + + map_[resource][sequence_number] = reply_thread; + } +} + +void ResourceReplyThreadRegistrar::Unregister(PP_Resource resource) { + base::AutoLock auto_lock(lock_); + map_.erase(resource); +} + +scoped_refptr<base::MessageLoopProxy> +ResourceReplyThreadRegistrar::GetTargetThreadAndUnregister( + PP_Resource resource, + int32_t sequence_number) { + base::AutoLock auto_lock(lock_); + ResourceMap::iterator resource_iter = map_.find(resource); + if (resource_iter == map_.end()) + return default_thread_; + + SequenceNumberMap::iterator sequence_number_iter = + resource_iter->second.find(sequence_number); + if (sequence_number_iter == resource_iter->second.end()) + return default_thread_; + + scoped_refptr<base::MessageLoopProxy> target = sequence_number_iter->second; + resource_iter->second.erase(sequence_number_iter); + return target; +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/resource_reply_thread_registrar.h b/ppapi/proxy/resource_reply_thread_registrar.h new file mode 100644 index 0000000..eef6d61 --- /dev/null +++ b/ppapi/proxy/resource_reply_thread_registrar.h @@ -0,0 +1,70 @@ +// Copyright 2013 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. + +#ifndef PPAPI_PROXY_RESOURCE_REPLY_THREAD_REGISTRAR_H_ +#define PPAPI_PROXY_RESOURCE_REPLY_THREAD_REGISTRAR_H_ + +#include <map> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/ppapi_proxy_export.h" + + +namespace base { +class MessageLoopProxy; +} + +namespace ppapi { + +class TrackedCallback; + +namespace proxy { + +// ResourceReplyThreadRegistrar records the handling thread for +// PpapiPluginMsg_ResourceReply messages. +// This class is thread safe. +class PPAPI_PROXY_EXPORT ResourceReplyThreadRegistrar + : public base::RefCountedThreadSafe<ResourceReplyThreadRegistrar> { + public: + explicit ResourceReplyThreadRegistrar( + scoped_refptr<base::MessageLoopProxy> default_thread); + + // This method can only be called while holding the Pepper proxy lock; the + // other methods can be called with/without the Pepper proxy lock. + void Register(PP_Resource resource, + int32_t sequence_number, + scoped_refptr<TrackedCallback> reply_thread_hint); + + void Unregister(PP_Resource resource); + + scoped_refptr<base::MessageLoopProxy> GetTargetThreadAndUnregister( + PP_Resource resource, + int32_t sequence_number); + + private: + friend class base::RefCountedThreadSafe<ResourceReplyThreadRegistrar>; + + typedef std::map<int32_t, scoped_refptr<base::MessageLoopProxy> > + SequenceNumberMap; + typedef std::map<PP_Resource, SequenceNumberMap> ResourceMap; + + ~ResourceReplyThreadRegistrar(); + + // The lock that protects the data members below. + // Please note that we should never try to acquire the Pepper proxy lock while + // holding |lock_|, otherwise we will cause deadlock. + base::Lock lock_; + ResourceMap map_; + scoped_refptr<base::MessageLoopProxy> default_thread_; + + DISALLOW_COPY_AND_ASSIGN(ResourceReplyThreadRegistrar); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_RESOURCE_REPLY_THREAD_REGISTRAR_H_ diff --git a/ppapi/proxy/talk_resource_unittest.cc b/ppapi/proxy/talk_resource_unittest.cc index e81a8a6..3b7d5ff 100644 --- a/ppapi/proxy/talk_resource_unittest.cc +++ b/ppapi/proxy/talk_resource_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "ppapi/proxy/locking_resource_releaser.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppapi_proxy_test.h" #include "ppapi/proxy/talk_resource.h" @@ -58,8 +59,7 @@ class TalkResourceTest : public PluginProxyTest { ResourceMessageReplyParams reply_params(params.pp_resource(), params.sequence()); reply_params.set_result(result); - IPC::Message reply_msg = PpapiPluginMsg_ResourceReply(reply_params, reply); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(reply_msg)); + PluginMessageFilter::DispatchResourceReplyForTest(reply_params, reply); } }; @@ -84,9 +84,8 @@ TEST_F(TalkResourceTest, GetPermission) { ResourceMessageReplyParams reply_params(params.pp_resource(), params.sequence()); reply_params.set_result(1); - IPC::Message reply = PpapiPluginMsg_ResourceReply( + PluginMessageFilter::DispatchResourceReplyForTest( reply_params, PpapiPluginMsg_Talk_RequestPermissionReply()); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(reply)); ASSERT_TRUE(callback.called()); ASSERT_EQ(1, callback.result()); @@ -111,9 +110,8 @@ TEST_F(TalkResourceTest, RequestPermission) { ResourceMessageReplyParams reply_params(params.pp_resource(), params.sequence()); reply_params.set_result(1); - IPC::Message reply = PpapiPluginMsg_ResourceReply( + PluginMessageFilter::DispatchResourceReplyForTest( reply_params, PpapiPluginMsg_Talk_RequestPermissionReply()); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(reply)); ASSERT_TRUE(callback.called()); ASSERT_EQ(1, callback.result()); @@ -143,9 +141,8 @@ TEST_F(TalkResourceTest, StartStopRemoting) { // Receive an event ASSERT_FALSE(event_callback.called()); ResourceMessageReplyParams notify_params(res.get(), 0); - IPC::Message notify = PpapiPluginMsg_ResourceReply( + PluginMessageFilter::DispatchResourceReplyForTest( notify_params, PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_ERROR)); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(notify)); ASSERT_TRUE(event_callback.called()); ASSERT_EQ(PP_TALKEVENT_ERROR, event_callback.result()); @@ -165,7 +162,8 @@ TEST_F(TalkResourceTest, StartStopRemoting) { // Events should be discarded at this point event_callback.Reset(); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(notify)); + PluginMessageFilter::DispatchResourceReplyForTest( + notify_params, PpapiPluginMsg_Talk_NotifyEvent(PP_TALKEVENT_ERROR)); ASSERT_FALSE(event_callback.called()); } diff --git a/ppapi/proxy/tcp_socket_resource_base.cc b/ppapi/proxy/tcp_socket_resource_base.cc index 6cb9d0b..fff2da3 100644 --- a/ppapi/proxy/tcp_socket_resource_base.cc +++ b/ppapi/proxy/tcp_socket_resource_base.cc @@ -84,7 +84,8 @@ int32_t TCPSocketResourceBase::BindImpl( BROWSER, PpapiHostMsg_TCPSocket_Bind(*addr), base::Bind(&TCPSocketResourceBase::OnPluginMsgBindReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -106,7 +107,8 @@ int32_t TCPSocketResourceBase::ConnectImpl( BROWSER, PpapiHostMsg_TCPSocket_Connect(host, port), base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -127,7 +129,8 @@ int32_t TCPSocketResourceBase::ConnectWithNetAddressImpl( BROWSER, PpapiHostMsg_TCPSocket_ConnectWithNetAddress(*addr), base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -172,7 +175,8 @@ int32_t TCPSocketResourceBase::SSLHandshakeImpl( trusted_certificates_, untrusted_certificates_), base::Bind(&TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -233,7 +237,8 @@ int32_t TCPSocketResourceBase::ReadImpl( BROWSER, PpapiHostMsg_TCPSocket_Read(bytes_to_read_), base::Bind(&TCPSocketResourceBase::OnPluginMsgReadReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -259,7 +264,8 @@ int32_t TCPSocketResourceBase::WriteImpl( BROWSER, PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)), base::Bind(&TCPSocketResourceBase::OnPluginMsgWriteReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -280,7 +286,8 @@ int32_t TCPSocketResourceBase::ListenImpl( BROWSER, PpapiHostMsg_TCPSocket_Listen(backlog), base::Bind(&TCPSocketResourceBase::OnPluginMsgListenReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -301,7 +308,8 @@ int32_t TCPSocketResourceBase::AcceptImpl( BROWSER, PpapiHostMsg_TCPSocket_Accept(), base::Bind(&TCPSocketResourceBase::OnPluginMsgAcceptReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -363,7 +371,8 @@ int32_t TCPSocketResourceBase::SetOptionImpl( BROWSER, PpapiHostMsg_TCPSocket_SetOption(name, option_data), base::Bind(&TCPSocketResourceBase::OnPluginMsgSetOptionReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } diff --git a/ppapi/proxy/udp_socket_resource_base.cc b/ppapi/proxy/udp_socket_resource_base.cc index 8ef3835..79ac348 100644 --- a/ppapi/proxy/udp_socket_resource_base.cc +++ b/ppapi/proxy/udp_socket_resource_base.cc @@ -91,7 +91,8 @@ int32_t UDPSocketResourceBase::SetOptionImpl( PpapiHostMsg_UDPSocket_SetOption(name, option_data), base::Bind(&UDPSocketResourceBase::OnPluginMsgSetOptionReply, base::Unretained(this), - callback)); + callback), + callback); return PP_OK_COMPLETIONPENDING; } @@ -112,7 +113,8 @@ int32_t UDPSocketResourceBase::BindImpl( BROWSER, PpapiHostMsg_UDPSocket_Bind(*addr), base::Bind(&UDPSocketResourceBase::OnPluginMsgBindReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } @@ -146,7 +148,8 @@ int32_t UDPSocketResourceBase::RecvFromImpl( BROWSER, PpapiHostMsg_UDPSocket_RecvFrom(bytes_to_read_), base::Bind(&UDPSocketResourceBase::OnPluginMsgRecvFromReply, - base::Unretained(this), addr)); + base::Unretained(this), addr), + callback); return PP_OK_COMPLETIONPENDING; } @@ -180,7 +183,8 @@ int32_t UDPSocketResourceBase::SendToImpl( BROWSER, PpapiHostMsg_UDPSocket_SendTo(std::string(buffer, num_bytes), *addr), base::Bind(&UDPSocketResourceBase::OnPluginMsgSendToReply, - base::Unretained(this))); + base::Unretained(this)), + callback); return PP_OK_COMPLETIONPENDING; } diff --git a/ppapi/proxy/websocket_resource_unittest.cc b/ppapi/proxy/websocket_resource_unittest.cc index ecd9111c..5cfc71a 100644 --- a/ppapi/proxy/websocket_resource_unittest.cc +++ b/ppapi/proxy/websocket_resource_unittest.cc @@ -8,6 +8,7 @@ #include "ppapi/c/ppb_var.h" #include "ppapi/c/ppb_websocket.h" #include "ppapi/proxy/locking_resource_releaser.h" +#include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppapi_proxy_test.h" #include "ppapi/proxy/websocket_resource.h" @@ -84,9 +85,8 @@ TEST_F(WebSocketResourceTest, Connect) { ResourceMessageReplyParams reply_params(params.pp_resource(), params.sequence()); reply_params.set_result(PP_OK); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply(reply_params, - PpapiPluginMsg_WebSocket_ConnectReply(url, protocol1)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, PpapiPluginMsg_WebSocket_ConnectReply(url, protocol1)); EXPECT_EQ(PP_OK, g_callback_result); EXPECT_EQ(true, g_callback_called); @@ -102,20 +102,17 @@ TEST_F(WebSocketResourceTest, UnsolicitedReplies) { // Check if BufferedAmountReply is handled. ResourceMessageReplyParams reply_params(res.get(), 0); reply_params.set_result(PP_OK); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_WebSocket_BufferedAmountReply(19760227u)))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, PpapiPluginMsg_WebSocket_BufferedAmountReply(19760227u)); uint64_t amount = websocket_iface->GetBufferedAmount(res.get()); EXPECT_EQ(19760227u, amount); // Check if StateReply is handled. - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply( - reply_params, - PpapiPluginMsg_WebSocket_StateReply( - static_cast<int32_t>(PP_WEBSOCKETREADYSTATE_CLOSING))))); + PluginMessageFilter::DispatchResourceReplyForTest( + reply_params, + PpapiPluginMsg_WebSocket_StateReply( + static_cast<int32_t>(PP_WEBSOCKETREADYSTATE_CLOSING))); PP_WebSocketReadyState state = websocket_iface->GetReadyState(res.get()); EXPECT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, state); @@ -143,9 +140,9 @@ TEST_F(WebSocketResourceTest, MessageError) { ResourceMessageReplyParams connect_reply_params(params.pp_resource(), params.sequence()); connect_reply_params.set_result(PP_OK); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply(connect_reply_params, - PpapiPluginMsg_WebSocket_ConnectReply(url, std::string())))); + PluginMessageFilter::DispatchResourceReplyForTest( + connect_reply_params, + PpapiPluginMsg_WebSocket_ConnectReply(url, std::string())); EXPECT_EQ(PP_OK, g_callback_result); EXPECT_TRUE(g_callback_called); @@ -157,9 +154,8 @@ TEST_F(WebSocketResourceTest, MessageError) { // Synthesize a WebSocket_ErrorReply message. ResourceMessageReplyParams error_reply_params(res.get(), 0); error_reply_params.set_result(PP_OK); - ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived( - PpapiPluginMsg_ResourceReply(error_reply_params, - PpapiPluginMsg_WebSocket_ErrorReply()))); + PluginMessageFilter::DispatchResourceReplyForTest( + error_reply_params, PpapiPluginMsg_WebSocket_ErrorReply()); EXPECT_EQ(PP_ERROR_FAILED, g_callback_result); EXPECT_TRUE(g_callback_called); diff --git a/ppapi/shared_impl/ppb_message_loop_shared.h b/ppapi/shared_impl/ppb_message_loop_shared.h index fd6d161..ed7bddb 100644 --- a/ppapi/shared_impl/ppb_message_loop_shared.h +++ b/ppapi/shared_impl/ppb_message_loop_shared.h @@ -13,6 +13,10 @@ #include "ppapi/shared_impl/resource.h" #include "ppapi/thunk/ppb_message_loop_api.h" +namespace base { +class MessageLoopProxy; +} + namespace tracked_objects { class Location; } @@ -44,6 +48,8 @@ class PPAPI_SHARED_EXPORT MessageLoopShared const base::Closure& closure, int64 delay_ms) = 0; + virtual base::MessageLoopProxy* GetMessageLoopProxy() = 0; + DISALLOW_COPY_AND_ASSIGN(MessageLoopShared); }; diff --git a/ppapi/shared_impl/tracked_callback.h b/ppapi/shared_impl/tracked_callback.h index 92af19b..c8b6c01 100644 --- a/ppapi/shared_impl/tracked_callback.h +++ b/ppapi/shared_impl/tracked_callback.h @@ -113,6 +113,10 @@ class PPAPI_SHARED_EXPORT TrackedCallback return !callback_.func; } + MessageLoopShared* target_loop() const { + return target_loop_.get(); + } + // Determines if the given callback is pending. A callback is pending if it // has not completed and has not been aborted. When receiving a plugin call, // use this to detect if |callback| represents an operation in progress. When |