Home | History | Annotate | Download | only in plugin
      1 /* -*- c++ -*- */
      2 /*
      3  * Copyright (c) 2012 The Chromium Authors. All rights reserved.
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 // A class containing information regarding a socket connection to a
      9 // service runtime instance.
     10 
     11 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_
     12 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_
     13 
     14 #include "native_client/src/include/nacl_macros.h"
     15 #include "native_client/src/include/nacl_scoped_ptr.h"
     16 #include "native_client/src/shared/platform/nacl_sync.h"
     17 #include "native_client/src/shared/srpc/nacl_srpc.h"
     18 #include "native_client/src/trusted/reverse_service/reverse_service.h"
     19 #include "native_client/src/trusted/weak_ref/weak_ref.h"
     20 
     21 #include "ppapi/cpp/completion_callback.h"
     22 #include "ppapi/native_client/src/trusted/plugin/utility.h"
     23 
     24 struct NaClFileInfo;
     25 
     26 namespace plugin {
     27 
     28 class ErrorInfo;
     29 class Plugin;
     30 class SelLdrLauncherChrome;
     31 class SrpcClient;
     32 class ServiceRuntime;
     33 
     34 // Struct of params used by StartSelLdr.  Use a struct so that callback
     35 // creation templates aren't overwhelmed with too many parameters.
     36 struct SelLdrStartParams {
     37   SelLdrStartParams(const std::string& url,
     38                     const PP_NaClFileInfo& file_info,
     39                     bool uses_irt,
     40                     bool uses_ppapi,
     41                     bool enable_dyncode_syscalls,
     42                     bool enable_exception_handling,
     43                     bool enable_crash_throttling)
     44       : url(url),
     45         file_info(file_info),
     46         uses_irt(uses_irt),
     47         uses_ppapi(uses_ppapi),
     48         enable_dyncode_syscalls(enable_dyncode_syscalls),
     49         enable_exception_handling(enable_exception_handling),
     50         enable_crash_throttling(enable_crash_throttling) {
     51   }
     52   std::string url;
     53   PP_NaClFileInfo file_info;
     54   bool uses_irt;
     55   bool uses_ppapi;
     56   bool enable_dev_interfaces;
     57   bool enable_dyncode_syscalls;
     58   bool enable_exception_handling;
     59   bool enable_crash_throttling;
     60 };
     61 
     62 // Callback resources are essentially our continuation state.
     63 struct OpenManifestEntryResource {
     64  public:
     65   OpenManifestEntryResource(const std::string& target_url,
     66                             struct NaClFileInfo* finfo,
     67                             bool* op_complete)
     68       : url(target_url),
     69         file_info(finfo),
     70         op_complete_ptr(op_complete) {}
     71   ~OpenManifestEntryResource();
     72 
     73   std::string url;
     74   struct NaClFileInfo* file_info;
     75   PP_NaClFileInfo pp_file_info;
     76   bool* op_complete_ptr;
     77 };
     78 
     79 // Do not invoke from the main thread, since the main methods will
     80 // invoke CallOnMainThread and then wait on a condvar for the task to
     81 // complete: if invoked from the main thread, the main method not
     82 // returning (and thus unblocking the main thread) means that the
     83 // main-thread continuation methods will never get called, and thus
     84 // we'd get a deadlock.
     85 class PluginReverseInterface: public nacl::ReverseInterface {
     86  public:
     87   PluginReverseInterface(nacl::WeakRefAnchor* anchor,
     88                          PP_Instance pp_instance,
     89                          ServiceRuntime* service_runtime,
     90                          pp::CompletionCallback init_done_cb);
     91 
     92   virtual ~PluginReverseInterface();
     93 
     94   void ShutDown();
     95 
     96   virtual void DoPostMessage(std::string message);
     97 
     98   virtual void StartupInitializationComplete();
     99 
    100   virtual bool OpenManifestEntry(std::string url_key,
    101                                  struct NaClFileInfo *info);
    102 
    103   virtual void ReportCrash();
    104 
    105   virtual void ReportExitStatus(int exit_status);
    106 
    107   // TODO(teravest): Remove this method once it's gone from
    108   // nacl::ReverseInterface.
    109   virtual int64_t RequestQuotaForWrite(std::string file_id,
    110                                        int64_t offset,
    111                                        int64_t bytes_to_write);
    112 
    113  protected:
    114   virtual void OpenManifestEntry_MainThreadContinuation(
    115       OpenManifestEntryResource* p,
    116       int32_t err);
    117 
    118   virtual void StreamAsFile_MainThreadContinuation(
    119       OpenManifestEntryResource* p,
    120       int32_t result);
    121 
    122  private:
    123   nacl::WeakRefAnchor* anchor_;  // holds a ref
    124   // Should be used only in main thread in WeakRef-protected callbacks.
    125   PP_Instance pp_instance_;
    126   ServiceRuntime* service_runtime_;
    127   NaClMutex mu_;
    128   NaClCondVar cv_;
    129   bool shutting_down_;
    130 
    131   pp::CompletionCallback init_done_cb_;
    132 };
    133 
    134 //  ServiceRuntime abstracts a NativeClient sel_ldr instance.
    135 class ServiceRuntime {
    136  public:
    137   ServiceRuntime(Plugin* plugin,
    138                  PP_Instance pp_instance,
    139                  bool main_service_runtime,
    140                  bool uses_nonsfi_mode,
    141                  pp::CompletionCallback init_done_cb);
    142   // The destructor terminates the sel_ldr process.
    143   ~ServiceRuntime();
    144 
    145   // Spawn the sel_ldr instance.
    146   void StartSelLdr(const SelLdrStartParams& params,
    147                    pp::CompletionCallback callback);
    148 
    149   // If starting sel_ldr from a background thread, wait for sel_ldr to
    150   // actually start. Returns |false| if timed out waiting for the process
    151   // to start. Otherwise, returns |true| if StartSelLdr is complete
    152   // (either successfully or unsuccessfully).
    153   bool WaitForSelLdrStart();
    154 
    155   // Signal to waiting threads that StartSelLdr is complete (either
    156   // successfully or unsuccessfully).
    157   void SignalStartSelLdrDone();
    158 
    159   // If starting the nexe from a background thread, wait for the nexe to
    160   // actually start. Returns |true| is the nexe started successfully.
    161   bool WaitForNexeStart();
    162 
    163   // Signal to waiting threads that LoadNexeAndStart is complete (either
    164   // successfully or unsuccessfully).
    165   void SignalNexeStarted(bool ok);
    166 
    167   // Establish an SrpcClient to the sel_ldr instance and start the nexe.
    168   // This function must be called on the main thread.
    169   // This function must only be called once.
    170   void StartNexe();
    171 
    172   // Starts the application channel to the nexe.
    173   SrpcClient* SetupAppChannel();
    174 
    175   bool RemoteLog(int severity, const std::string& msg);
    176   Plugin* plugin() const { return plugin_; }
    177   void Shutdown();
    178 
    179   bool main_service_runtime() const { return main_service_runtime_; }
    180 
    181  private:
    182   NACL_DISALLOW_COPY_AND_ASSIGN(ServiceRuntime);
    183   bool StartNexeInternal();
    184 
    185   bool SetupCommandChannel();
    186   bool InitReverseService();
    187   bool StartModule();
    188   void ReapLogs();
    189 
    190   void ReportLoadError(const ErrorInfo& error_info);
    191 
    192   NaClSrpcChannel command_channel_;
    193   Plugin* plugin_;
    194   PP_Instance pp_instance_;
    195   bool main_service_runtime_;
    196   bool uses_nonsfi_mode_;
    197   nacl::ReverseService* reverse_service_;
    198   nacl::scoped_ptr<SelLdrLauncherChrome> subprocess_;
    199 
    200   nacl::WeakRefAnchor* anchor_;
    201 
    202   PluginReverseInterface* rev_interface_;
    203 
    204   // Mutex and CondVar to protect start_sel_ldr_done_ and nexe_started_.
    205   NaClMutex mu_;
    206   NaClCondVar cond_;
    207   bool start_sel_ldr_done_;
    208   bool start_nexe_done_;
    209   bool nexe_started_ok_;
    210 
    211   NaClHandle bootstrap_channel_;
    212 };
    213 
    214 }  // namespace plugin
    215 
    216 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_
    217