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