Home | History | Annotate | Download | only in nacl_irt
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ppapi/nacl_irt/plugin_startup.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/file_descriptor_posix.h"
      9 #include "base/logging.h"
     10 #include "base/synchronization/waitable_event.h"
     11 #include "base/threading/thread.h"
     12 #include "ipc/ipc_channel_handle.h"
     13 #include "ppapi/nacl_irt/manifest_service.h"
     14 #include "ppapi/shared_impl/ppb_audio_shared.h"
     15 
     16 namespace ppapi {
     17 namespace {
     18 
     19 int g_nacl_browser_ipc_fd = -1;
     20 int g_nacl_renderer_ipc_fd = -1;
     21 int g_manifest_service_fd = -1;
     22 
     23 base::WaitableEvent* g_shutdown_event = NULL;
     24 base::Thread* g_io_thread = NULL;
     25 ManifestService* g_manifest_service = NULL;
     26 
     27 // Creates the manifest service on IO thread so that its Listener's thread and
     28 // IO thread are shared. Upon completion of the manifest service creation,
     29 // event is signaled.
     30 void StartUpManifestServiceOnIOThread(base::WaitableEvent* event) {
     31   // The start up must be called only once.
     32   DCHECK(!g_manifest_service);
     33   // manifest_service_fd must be set.
     34   DCHECK_NE(g_manifest_service_fd, -1);
     35   // IOThread and shutdown event must be initialized in advance.
     36   DCHECK(g_io_thread);
     37   DCHECK(g_shutdown_event);
     38 
     39   g_manifest_service = new ManifestService(
     40       IPC::ChannelHandle(
     41           "NaCl IPC", base::FileDescriptor(g_manifest_service_fd, false)),
     42       g_io_thread->message_loop_proxy(),
     43       g_shutdown_event);
     44   event->Signal();
     45 }
     46 
     47 }  // namespace
     48 
     49 void SetIPCFileDescriptors(
     50     int browser_ipc_fd, int renderer_ipc_fd, int manifest_service_fd) {
     51   // The initialization must be only once.
     52   DCHECK_EQ(g_nacl_browser_ipc_fd, -1);
     53   DCHECK_EQ(g_nacl_renderer_ipc_fd, -1);
     54   DCHECK_EQ(g_manifest_service_fd, -1);
     55   g_nacl_browser_ipc_fd = browser_ipc_fd;
     56   g_nacl_renderer_ipc_fd = renderer_ipc_fd;
     57   g_manifest_service_fd = manifest_service_fd;
     58 }
     59 
     60 void StartUpPlugin() {
     61   // The start up must be called only once.
     62   DCHECK(!g_shutdown_event);
     63   DCHECK(!g_io_thread);
     64 
     65   g_shutdown_event = new base::WaitableEvent(true, false);
     66   g_io_thread = new base::Thread("Chrome_NaClIOThread");
     67   g_io_thread->StartWithOptions(
     68       base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
     69 
     70   if (g_manifest_service_fd != -1) {
     71     // Manifest service must be created on IOThread so that the main message
     72     // handling will be done on the thread, which has a message loop
     73     // even before irt_ppapi_start invocation.
     74     // TODO(hidehiko,dmichael): This works, but is probably not well designed
     75     // usage. Once a better approach is made, replace this by that way.
     76     // (crbug.com/364241).
     77     base::WaitableEvent event(true, false);
     78     g_io_thread->message_loop_proxy()->PostTask(
     79         FROM_HERE,
     80         base::Bind(StartUpManifestServiceOnIOThread, &event));
     81     event.Wait();
     82   }
     83 
     84   PPB_Audio_Shared::SetNaClMode();
     85 }
     86 
     87 int GetBrowserIPCFileDescriptor() {
     88   // The descriptor must be initialized in advance.
     89   DCHECK_NE(g_nacl_browser_ipc_fd, -1);
     90   return g_nacl_browser_ipc_fd;
     91 }
     92 
     93 int GetRendererIPCFileDescriptor() {
     94   // The descriptor must be initialized in advance.
     95   DCHECK_NE(g_nacl_renderer_ipc_fd, -1);
     96   return g_nacl_renderer_ipc_fd;
     97 }
     98 
     99 base::WaitableEvent* GetShutdownEvent() {
    100   // The shutdown event must be initialized in advance.
    101   DCHECK(g_shutdown_event);
    102   return g_shutdown_event;
    103 }
    104 
    105 base::Thread* GetIOThread() {
    106   // The IOThread must be initialized in advance.
    107   DCHECK(g_io_thread);
    108   return g_io_thread;
    109 }
    110 
    111 ManifestService* GetManifestService() {
    112   return g_manifest_service;
    113 }
    114 
    115 }  // namespace ppapi
    116