summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/proxy/host_dispatcher.cc12
-rw-r--r--ppapi/proxy/host_dispatcher.h5
-rw-r--r--ppapi/proxy/plugin_dispatcher.cc76
-rw-r--r--ppapi/proxy/plugin_dispatcher.h30
-rw-r--r--ppapi/proxy/ppapi_messages_internal.h23
-rw-r--r--ppapi/proxy/ppapi_proxy_test.cc4
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());
}