Index: ppapi/nacl_irt/plugin_startup.cc |
diff --git a/ppapi/nacl_irt/plugin_startup.cc b/ppapi/nacl_irt/plugin_startup.cc |
index a3b5bc207e67acd95aab07893815941e4d7eeda1..4a7853f73f251755763e25a38d3c7ebfc7628dc3 100644 |
--- a/ppapi/nacl_irt/plugin_startup.cc |
+++ b/ppapi/nacl_irt/plugin_startup.cc |
@@ -2,28 +2,55 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "ppapi/nacl_irt/plugin_startup.h" |
+ |
+#include "base/bind.h" |
+#include "base/file_descriptor_posix.h" |
#include "base/logging.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/threading/thread.h" |
-#include "ppapi/nacl_irt/plugin_startup.h" |
+#include "ipc/ipc_channel_handle.h" |
+#include "ppapi/nacl_irt/embedder_service.h" |
namespace ppapi { |
namespace { |
int g_nacl_browser_ipc_fd = -1; |
int g_nacl_renderer_ipc_fd = -1; |
+int g_embedder_service_fd = -1; |
base::WaitableEvent* g_shutdown_event = NULL; |
base::Thread* g_io_thread = NULL; |
+EmbedderService* g_embedder_service = NULL; |
+ |
+void StartUpEmbedderServiceOnIOThread(base::WaitableEvent* event) { |
+ // The start up must be called only once. |
+ DCHECK(!g_embedder_service); |
+ // embedder_service_fd must be set. |
+ DCHECK_NE(g_embedder_service_fd, -1); |
+ // IOThread and shutdown event must be initialized in advance. |
+ DCHECK(g_io_thread); |
+ DCHECK(g_shutdown_event); |
+ |
+ g_embedder_service = new EmbedderService( |
+ IPC::ChannelHandle( |
+ "NaCl IPC", base::FileDescriptor(g_embedder_service_fd, false)), |
+ g_io_thread->message_loop_proxy(), |
+ g_shutdown_event); |
+ event->Signal(); |
+} |
} // namespace |
-void SetIPCFileDescriptors(int browser_ipc_fd, int renderer_ipc_fd) { |
+void SetIPCFileDescriptors( |
+ int browser_ipc_fd, int renderer_ipc_fd, int embedder_service_fd) { |
// The initialization must be only once. |
DCHECK_EQ(g_nacl_browser_ipc_fd, -1); |
DCHECK_EQ(g_nacl_renderer_ipc_fd, -1); |
+ DCHECK_EQ(g_embedder_service_fd, -1); |
g_nacl_browser_ipc_fd = browser_ipc_fd; |
g_nacl_renderer_ipc_fd = renderer_ipc_fd; |
+ g_embedder_service_fd = embedder_service_fd; |
} |
void StartUpPlugin() { |
@@ -35,6 +62,17 @@ void StartUpPlugin() { |
g_io_thread = new base::Thread("Chrome_NaClIOThread"); |
g_io_thread->StartWithOptions( |
base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
+ |
+ if (g_embedder_service_fd != -1) { |
+ // EmbedderService must be created on IOThread so that the main message |
+ // handling will be done on the thread, which has a message loop |
+ // even before irt_ppapi_start invocation. |
+ base::WaitableEvent event(true, false); |
+ g_io_thread->message_loop_proxy()->PostTask( |
+ FROM_HERE, |
+ base::Bind(StartUpEmbedderServiceOnIOThread, &event)); |
+ event.Wait(); |
+ } |
} |
int GetBrowserIPCFileDescriptor() { |