Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: chrome/ppapi_plugin/ppapi_thread.cc

Issue 6486034: Share PPAPI out-of-process plugins between renderer processes.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/ppapi_plugin/ppapi_thread.h ('k') | chrome/renderer/pepper_plugin_delegate_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/ppapi_plugin/ppapi_thread.h" 5 #include "chrome/ppapi_plugin/ppapi_thread.h"
6 6
7 #include <limits>
8
7 #include "base/process_util.h" 9 #include "base/process_util.h"
10 #include "base/rand_util.h"
8 #include "chrome/common/child_process.h" 11 #include "chrome/common/child_process.h"
9 #include "ipc/ipc_channel_handle.h" 12 #include "ipc/ipc_channel_handle.h"
10 #include "ipc/ipc_sync_channel.h" 13 #include "ipc/ipc_sync_channel.h"
14 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/ppp.h" 15 #include "ppapi/c/ppp.h"
12 #include "ppapi/proxy/plugin_dispatcher.h" 16 #include "ppapi/proxy/plugin_dispatcher.h"
13 #include "ppapi/proxy/ppapi_messages.h" 17 #include "ppapi/proxy/ppapi_messages.h"
14 18
15 #if defined(OS_POSIX)
16 #include "base/eintr_wrapper.h"
17 #include "ipc/ipc_channel_posix.h"
18 #endif
19
20 PpapiThread::PpapiThread() 19 PpapiThread::PpapiThread()
21 #if defined(OS_POSIX) 20 : get_plugin_interface_(NULL),
22 : renderer_fd_(-1) 21 local_pp_module_(
23 #endif 22 base::RandInt(0, std::numeric_limits<PP_Module>::max())) {
24 {
25 } 23 }
26 24
27 PpapiThread::~PpapiThread() { 25 PpapiThread::~PpapiThread() {
26 if (library_.is_valid()) {
27 // The ShutdownModule function is optional.
28 pp::proxy::Dispatcher::ShutdownModuleFunc shutdown_module =
29 reinterpret_cast<pp::proxy::Dispatcher::ShutdownModuleFunc>(
30 library_.GetFunctionPointer("PPP_ShutdownModule"));
31 if (shutdown_module)
32 shutdown_module();
33 }
28 } 34 }
29 35
30 // The "regular" ChildThread implements this function and does some standard 36 // The "regular" ChildThread implements this function and does some standard
31 // dispatching, then uses the message router. We don't actually need any of 37 // dispatching, then uses the message router. We don't actually need any of
32 // this so this function just overrides that one. 38 // this so this function just overrides that one.
33 // 39 //
34 // Note that this function is called only for messages from the channel to the 40 // Note that this function is called only for messages from the channel to the
35 // browser process. Messages from the renderer process are sent via a different 41 // browser process. Messages from the renderer process are sent via a different
36 // channel that ends up at Dispatcher::OnMessageReceived. 42 // channel that ends up at Dispatcher::OnMessageReceived.
37 bool PpapiThread::OnMessageReceived(const IPC::Message& msg) { 43 bool PpapiThread::OnMessageReceived(const IPC::Message& msg) {
38 IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg) 44 IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
39 IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin) 45 IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin)
46 IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnMsgCreateChannel)
40 IPC_END_MESSAGE_MAP() 47 IPC_END_MESSAGE_MAP()
41 return true; 48 return true;
42 } 49 }
43 50
44 void PpapiThread::OnMsgLoadPlugin(base::ProcessHandle host_process_handle, 51 void PpapiThread::OnMsgLoadPlugin(const FilePath& path) {
45 const FilePath& path, 52 base::ScopedNativeLibrary library(base::LoadNativeLibrary(path));
46 int renderer_id) { 53 if (!library.is_valid())
47 IPC::ChannelHandle channel_handle; 54 return;
48 if (!LoadPluginLib(host_process_handle, path) || 55
49 !SetupRendererChannel(renderer_id, &channel_handle)) { 56 // Get the GetInterface function (required).
50 // An empty channel handle indicates error. 57 get_plugin_interface_ =
51 Send(new PpapiHostMsg_PluginLoaded(IPC::ChannelHandle())); 58 reinterpret_cast<pp::proxy::Dispatcher::GetInterfaceFunc>(
59 library.GetFunctionPointer("PPP_GetInterface"));
60 if (!get_plugin_interface_) {
61 LOG(WARNING) << "No PPP_GetInterface in plugin library";
52 return; 62 return;
53 } 63 }
54 64
55 Send(new PpapiHostMsg_PluginLoaded(channel_handle));
56 }
57
58 bool PpapiThread::LoadPluginLib(base::ProcessHandle host_process_handle,
59 const FilePath& path) {
60 base::ScopedNativeLibrary library(base::LoadNativeLibrary(path));
61 if (!library.is_valid())
62 return false;
63
64 // Get the GetInterface function (required).
65 pp::proxy::Dispatcher::GetInterfaceFunc get_interface =
66 reinterpret_cast<pp::proxy::Dispatcher::GetInterfaceFunc>(
67 library.GetFunctionPointer("PPP_GetInterface"));
68 if (!get_interface) {
69 LOG(WARNING) << "No PPP_GetInterface in plugin library";
70 return false;
71 }
72
73 // Get the InitializeModule function (required). 65 // Get the InitializeModule function (required).
74 pp::proxy::Dispatcher::InitModuleFunc init_module = 66 pp::proxy::Dispatcher::InitModuleFunc init_module =
75 reinterpret_cast<pp::proxy::Dispatcher::InitModuleFunc>( 67 reinterpret_cast<pp::proxy::Dispatcher::InitModuleFunc>(
76 library.GetFunctionPointer("PPP_InitializeModule")); 68 library.GetFunctionPointer("PPP_InitializeModule"));
77 if (!init_module) { 69 if (!init_module) {
78 LOG(WARNING) << "No PPP_InitializeModule in plugin library"; 70 LOG(WARNING) << "No PPP_InitializeModule in plugin library";
79 return false; 71 return;
72 }
73 int32_t init_error = init_module(
74 local_pp_module_,
75 &pp::proxy::PluginDispatcher::GetInterfaceFromDispatcher);
76 if (init_error != PP_OK) {
77 LOG(WARNING) << "InitModule failed with error " << init_error;
78 return;
80 } 79 }
81 80
82 // Get the ShutdownModule function (optional).
83 pp::proxy::Dispatcher::ShutdownModuleFunc shutdown_module =
84 reinterpret_cast<pp::proxy::Dispatcher::ShutdownModuleFunc>(
85 library.GetFunctionPointer("PPP_ShutdownModule"));
86
87 library_.Reset(library.Release()); 81 library_.Reset(library.Release());
88 dispatcher_.reset(new pp::proxy::PluginDispatcher(
89 host_process_handle, get_interface, init_module, shutdown_module));
90 return true;
91 } 82 }
92 83
93 bool PpapiThread::SetupRendererChannel(int renderer_id, 84 void PpapiThread::OnMsgCreateChannel(base::ProcessHandle host_process_handle,
85 int renderer_id) {
86 IPC::ChannelHandle channel_handle;
87 if (!library_.is_valid() || // Plugin couldn't be loaded.
88 !SetupRendererChannel(host_process_handle, renderer_id,
89 &channel_handle)) {
90 Send(new PpapiHostMsg_ChannelCreated(IPC::ChannelHandle()));
91 return;
92 }
93
94 Send(new PpapiHostMsg_ChannelCreated(channel_handle));
95 }
96
97 bool PpapiThread::SetupRendererChannel(base::ProcessHandle host_process_handle,
98 int renderer_id,
94 IPC::ChannelHandle* handle) { 99 IPC::ChannelHandle* handle) {
100 pp::proxy::PluginDispatcher* dispatcher = new pp::proxy::PluginDispatcher(
101 host_process_handle, get_plugin_interface_);
102
95 IPC::ChannelHandle plugin_handle; 103 IPC::ChannelHandle plugin_handle;
96 plugin_handle.name = StringPrintf("%d.r%d", base::GetCurrentProcId(), 104 plugin_handle.name = StringPrintf("%d.r%d", base::GetCurrentProcId(),
97 renderer_id); 105 renderer_id);
98 if (!dispatcher_->InitWithChannel( 106 if (!dispatcher->InitWithChannel(
99 ChildProcess::current()->io_message_loop(), 107 ChildProcess::current()->io_message_loop(),
100 plugin_handle, false, 108 plugin_handle, false,
101 ChildProcess::current()->GetShutDownEvent())) 109 ChildProcess::current()->GetShutDownEvent()))
102 return false; 110 return false;
103 111
104 handle->name = plugin_handle.name; 112 handle->name = plugin_handle.name;
105 #if defined(OS_POSIX) 113 #if defined(OS_POSIX)
106 // On POSIX, pass the renderer-side FD. 114 // On POSIX, pass the renderer-side FD.
107 renderer_fd_ = dispatcher_->channel()->GetClientFileDescriptor(); 115 handle->socket = base::FileDescriptor(dispatcher->GetRendererFD(), false);
108 handle->socket = base::FileDescriptor(renderer_fd_, false);
109 #endif 116 #endif
117
110 return true; 118 return true;
111 } 119 }
112 120
113 #if defined(OS_POSIX)
114 void PpapiThread::CloseRendererFD() {
115 if (renderer_fd_ != -1) {
116 if (HANDLE_EINTR(close(renderer_fd_)) < 0)
117 PLOG(ERROR) << "close";
118 renderer_fd_ = -1;
119 }
120 }
121 #endif
OLDNEW
« no previous file with comments | « chrome/ppapi_plugin/ppapi_thread.h ('k') | chrome/renderer/pepper_plugin_delegate_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698