diff options
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/proxy/host_dispatcher.cc | 12 | ||||
-rw-r--r-- | ppapi/proxy/host_dispatcher.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/plugin_dispatcher.cc | 76 | ||||
-rw-r--r-- | ppapi/proxy/plugin_dispatcher.h | 30 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages_internal.h | 23 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_proxy_test.cc | 4 |
6 files changed, 89 insertions, 61 deletions
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index 7978786..fce2b13 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc @@ -36,14 +36,6 @@ HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, } HostDispatcher::~HostDispatcher() { - // Notify the plugin that it should exit. - Send(new PpapiMsg_Shutdown()); -} - -bool HostDispatcher::InitializeModule() { - bool init_result = false; - Send(new PpapiMsg_InitializeModule(pp_module(), &init_result)); - return init_result; } // static @@ -116,6 +108,10 @@ bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) { return proxy->OnMessageReceived(msg); } +void HostDispatcher::OnChannelError() { + // TODO(brettw) plugin has crashed, handle this. +} + const void* HostDispatcher::GetProxiedInterface(const std::string& interface) { // First see if we even have a proxy for this interface. const InterfaceProxy::Info* info = GetPPPInterfaceInfo(interface); diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h index f405f71..e38fca6 100644 --- a/ppapi/proxy/host_dispatcher.h +++ b/ppapi/proxy/host_dispatcher.h @@ -48,15 +48,12 @@ class HostDispatcher : public Dispatcher { HostDispatcher* dispatcher); static void RemoveForInstance(PP_Instance instance); - // Calls the plugin's PPP_InitializeModule function and returns true if - // the call succeeded. - bool InitializeModule(); - // Dispatcher overrides. virtual bool IsPlugin() const; // IPC::Channel::Listener. virtual bool OnMessageReceived(const IPC::Message& msg); + virtual void OnChannelError(); // Proxied version of calling GetInterface on the plugin. This will check // if the plugin supports the given interface (with caching) and returns the diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index b30f6da..1f4454c 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -16,6 +16,11 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppp_class_proxy.h" +#if defined(OS_POSIX) +#include "base/eintr_wrapper.h" +#include "ipc/ipc_channel_posix.h" +#endif + namespace pp { namespace proxy { @@ -24,23 +29,15 @@ namespace { typedef std::map<PP_Instance, PluginDispatcher*> InstanceToDispatcherMap; InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; -const void* GetInterfaceFromDispatcher(const char* interface) { - // All interfaces the plugin requests of the browser are "PPB". - const InterfaceProxy::Info* info = Dispatcher::GetPPBInterfaceInfo(interface); - if (!info) - return NULL; - return info->interface; -} - } // namespace PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle, - GetInterfaceFunc get_interface, - InitModuleFunc init_module, - ShutdownModuleFunc shutdown_module) - : Dispatcher(remote_process_handle, get_interface), - init_module_(init_module), - shutdown_module_(shutdown_module) { + GetInterfaceFunc get_interface) + : Dispatcher(remote_process_handle, get_interface) +#if defined(OS_POSIX) + , renderer_fd_(-1) +#endif + { SetSerializationRules(new PluginVarSerializationRules); // As a plugin, we always support the PPP_Class interface. There's no @@ -49,8 +46,9 @@ PluginDispatcher::PluginDispatcher(base::ProcessHandle remote_process_handle, } PluginDispatcher::~PluginDispatcher() { - if (shutdown_module_) - shutdown_module_(); +#if defined(OS_POSIX) + CloseRendererFD(); +#endif } // static @@ -64,6 +62,16 @@ PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) { return found->second; } +// static +const void* PluginDispatcher::GetInterfaceFromDispatcher( + const char* interface) { + // All interfaces the plugin requests of the browser are "PPB". + const InterfaceProxy::Info* info = GetPPBInterfaceInfo(interface); + if (!info) + return NULL; + return info->interface; +} + bool PluginDispatcher::IsPlugin() const { return true; } @@ -78,8 +86,6 @@ bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg) IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface) - IPC_MESSAGE_HANDLER(PpapiMsg_InitializeModule, OnMsgInitializeModule) - IPC_MESSAGE_HANDLER(PpapiMsg_Shutdown, OnMsgShutdown) IPC_END_MESSAGE_MAP() return handled; } @@ -122,6 +128,14 @@ bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) { return proxy->OnMessageReceived(msg); } +void PluginDispatcher::OnChannelError() { + // The renderer has crashed. This channel and all instances associated with + // it are no longer valid. + ForceFreeAllInstances(); + // TODO(brettw) free resources too! + delete this; +} + void PluginDispatcher::DidCreateInstance(PP_Instance instance) { if (!g_instance_to_dispatcher) g_instance_to_dispatcher = new InstanceToDispatcherMap; @@ -152,16 +166,24 @@ InstanceData* PluginDispatcher::GetInstanceData(PP_Instance instance) { return (it == instance_map_.end()) ? NULL : &it->second; } -void PluginDispatcher::OnMsgInitializeModule(PP_Module pp_module, - bool* result) { - set_pp_module(pp_module); - *result = init_module_(pp_module, &GetInterfaceFromDispatcher) == PP_OK; +#if defined(OS_POSIX) +int PluginDispatcher::GetRendererFD() { + if (renderer_fd_ == -1) + renderer_fd_ = channel()->GetClientFileDescriptor(); + return renderer_fd_; +} + +void PluginDispatcher::CloseRendererFD() { + if (renderer_fd_ != -1) { + if (HANDLE_EINTR(close(renderer_fd_)) < 0) + PLOG(ERROR) << "close"; + renderer_fd_ = -1; + } } +#endif -void PluginDispatcher::OnMsgShutdown() { - if (shutdown_module_) - shutdown_module_(); - MessageLoop::current()->Quit(); +void PluginDispatcher::ForceFreeAllInstances() { + // TODO(brettw) implement freeing instances on crash. } void PluginDispatcher::OnMsgSupportsInterface( diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h index 8f27ac0..0b219f4 100644 --- a/ppapi/proxy/plugin_dispatcher.h +++ b/ppapi/proxy/plugin_dispatcher.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,6 +10,7 @@ #include "base/hash_tables.h" #include "base/process.h" #include "base/scoped_ptr.h" +#include "build/build_config.h" #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/dispatcher.h" @@ -36,9 +37,7 @@ class PluginDispatcher : public Dispatcher { // // You must call Dispatcher::InitWithChannel after the constructor. PluginDispatcher(base::ProcessHandle remote_process_handle, - GetInterfaceFunc get_interface, - InitModuleFunc init_module, - ShutdownModuleFunc shutdown_module); + GetInterfaceFunc get_interface); ~PluginDispatcher(); // The plugin side maintains a mapping from PP_Instance to Dispatcher so @@ -47,11 +46,14 @@ class PluginDispatcher : public Dispatcher { // DidCreateInstance/DidDestroyInstance. static PluginDispatcher* GetForInstance(PP_Instance instance); + static const void* GetInterfaceFromDispatcher(const char* interface); + // Dispatcher overrides. virtual bool IsPlugin() const; // IPC::Channel::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& msg); + virtual void OnChannelError(); // Keeps track of which dispatcher to use for each instance, active instances // and tracks associated data like the current size. @@ -62,16 +64,28 @@ class PluginDispatcher : public Dispatcher { // correspond to a known instance. InstanceData* GetInstanceData(PP_Instance instance); +#if defined(OS_POSIX) + // See renderer_fd_ below. + int GetRendererFD(); + void CloseRendererFD(); +#endif + private: friend class PluginDispatcherTest; + // Notifies all live instances that they're now closed. This is used when + // a renderer crashes or some other error is received. + void ForceFreeAllInstances(); + // IPC message handlers. - void OnMsgInitializeModule(PP_Module pp_module, bool* result); - void OnMsgShutdown(); void OnMsgSupportsInterface(const std::string& interface_name, bool* result); - InitModuleFunc init_module_; - ShutdownModuleFunc shutdown_module_; +#if defined(OS_POSIX) + // FD for the renderer end of the socket. It is closed when the IPC layer + // indicates that the channel is connected, proving that the renderer has + // access to its side of the socket. + int renderer_fd_; +#endif // All target proxies currently created. These are ones that receive // messages. diff --git a/ppapi/proxy/ppapi_messages_internal.h b/ppapi/proxy/ppapi_messages_internal.h index b181b2e..7cab708 100644 --- a/ppapi/proxy/ppapi_messages_internal.h +++ b/ppapi/proxy/ppapi_messages_internal.h @@ -12,16 +12,13 @@ // These are from the plugin to the renderer // Loads the given plugin. -IPC_MESSAGE_CONTROL3(PpapiMsg_LoadPlugin, - base::ProcessHandle /* host_process_handle */, - FilePath /* path */, - int /* renderer_id */) - -IPC_SYNC_MESSAGE_CONTROL1_1(PpapiMsg_InitializeModule, - PP_Module /* module_id */, - bool /* result */) +IPC_MESSAGE_CONTROL1(PpapiMsg_LoadPlugin, FilePath /* path */) -IPC_MESSAGE_CONTROL0(PpapiMsg_Shutdown) +// Creates a channel to talk to a renderer. The plugin will respond with +// PpapiHostMsg_ChannelCreated. +IPC_MESSAGE_CONTROL2(PpapiMsg_CreateChannel, + base::ProcessHandle /* host_process_handle */, + int /* renderer_id */); // Sent in both directions to see if the other side supports the given // interface. @@ -152,8 +149,12 @@ IPC_MESSAGE_ROUTED3(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack, // ----------------------------------------------------------------------------- // These are from the plugin to the renderer. -// Reply to PpapiMsg_LoadPlugin. -IPC_MESSAGE_CONTROL1(PpapiHostMsg_PluginLoaded, + +// Reply to PpapiMsg_CreateChannel. The handle will be NULL if the channel +// could not be established. This could be because the IPC could not be created +// for some weird reason, but more likely that the plugin failed to load or +// initialize properly. +IPC_MESSAGE_CONTROL1(PpapiHostMsg_ChannelCreated, IPC::ChannelHandle /* handle */) // PPB_Audio. diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc index 1b75001..fffb20c 100644 --- a/ppapi/proxy/ppapi_proxy_test.cc +++ b/ppapi/proxy/ppapi_proxy_test.cc @@ -94,9 +94,7 @@ void PluginProxyTest::SetUp() { plugin_dispatcher_.reset(new PluginDispatcher( base::Process::Current().handle(), - &MockGetInterface, - &MockInitModule, - &MockShutdownModuleFunc)); + &MockGetInterface)); plugin_dispatcher_->InitWithTestSink(&sink()); plugin_dispatcher_->DidCreateInstance(pp_instance()); } |