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.
8 // A class containing information regarding a socket connection to a
9 // service runtime instance.
11 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_
12 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_
16 #include "native_client/src/include/nacl_macros.h"
17 #include "native_client/src/include/nacl_scoped_ptr.h"
18 #include "native_client/src/include/nacl_string.h"
19 #include "native_client/src/shared/platform/nacl_sync.h"
20 #include "native_client/src/shared/srpc/nacl_srpc.h"
21 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
22 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
23 #include "native_client/src/trusted/reverse_service/reverse_service.h"
24 #include "native_client/src/trusted/weak_ref/weak_ref.h"
26 #include "ppapi/cpp/completion_callback.h"
28 #include "ppapi/native_client/src/trusted/plugin/utility.h"
45 class PnaclCoordinator;
49 // Struct of params used by StartSelLdr. Use a struct so that callback
50 // creation templates aren't overwhelmed with too many parameters.
51 struct SelLdrStartParams {
52 SelLdrStartParams(const nacl::string& url,
53 ErrorInfo* error_info,
56 bool enable_dev_interfaces,
57 bool enable_dyncode_syscalls,
58 bool enable_exception_handling,
59 bool enable_crash_throttling)
61 error_info(error_info),
63 uses_ppapi(uses_ppapi),
64 enable_dev_interfaces(enable_dev_interfaces),
65 enable_dyncode_syscalls(enable_dyncode_syscalls),
66 enable_exception_handling(enable_exception_handling),
67 enable_crash_throttling(enable_crash_throttling) {
70 ErrorInfo* error_info;
73 bool enable_dev_interfaces;
74 bool enable_dyncode_syscalls;
75 bool enable_exception_handling;
76 bool enable_crash_throttling;
79 // Callback resources are essentially our continuation state.
81 struct LogToJavaScriptConsoleResource {
83 explicit LogToJavaScriptConsoleResource(std::string msg)
88 struct PostMessageResource {
90 explicit PostMessageResource(std::string msg)
95 struct OpenManifestEntryResource {
97 OpenManifestEntryResource(const std::string& target_url,
98 struct NaClFileInfo* finfo,
104 op_complete_ptr(op_complete) {}
106 struct NaClFileInfo* file_info;
107 ErrorInfo* error_info;
108 bool* op_complete_ptr;
111 struct CloseManifestEntryResource {
113 CloseManifestEntryResource(int32_t desc_to_close,
116 : desc(desc_to_close),
117 op_complete_ptr(op_complete),
118 op_result_ptr(op_result) {}
121 bool* op_complete_ptr;
125 struct QuotaRequest {
127 QuotaRequest(PP_Resource pp_resource,
128 int64_t start_offset,
129 int64_t quota_bytes_requested,
130 int64_t* quota_bytes_granted,
132 : resource(pp_resource),
133 offset(start_offset),
134 bytes_requested(quota_bytes_requested),
135 bytes_granted(quota_bytes_granted),
136 op_complete_ptr(op_complete) { }
138 PP_Resource resource;
140 int64_t bytes_requested;
141 int64_t* bytes_granted;
142 bool* op_complete_ptr;
145 // Do not invoke from the main thread, since the main methods will
146 // invoke CallOnMainThread and then wait on a condvar for the task to
147 // complete: if invoked from the main thread, the main method not
148 // returning (and thus unblocking the main thread) means that the
149 // main-thread continuation methods will never get called, and thus
150 // we'd get a deadlock.
151 class PluginReverseInterface: public nacl::ReverseInterface {
153 PluginReverseInterface(nacl::WeakRefAnchor* anchor,
155 const Manifest* manifest,
156 ServiceRuntime* service_runtime,
157 pp::CompletionCallback init_done_cb,
158 pp::CompletionCallback crash_cb);
160 virtual ~PluginReverseInterface();
164 virtual void Log(nacl::string message);
166 virtual void DoPostMessage(nacl::string message);
168 virtual void StartupInitializationComplete();
170 virtual bool EnumerateManifestKeys(std::set<nacl::string>* out_keys);
172 virtual bool OpenManifestEntry(nacl::string url_key,
173 struct NaClFileInfo *info);
175 virtual bool CloseManifestEntry(int32_t desc);
177 virtual void ReportCrash();
179 virtual void ReportExitStatus(int exit_status);
181 virtual int64_t RequestQuotaForWrite(nacl::string file_id,
183 int64_t bytes_to_write);
185 void AddQuotaManagedFile(const nacl::string& file_id,
186 const pp::FileIO& file_io);
187 void AddTempQuotaManagedFile(const nacl::string& file_id);
190 virtual void Log_MainThreadContinuation(LogToJavaScriptConsoleResource* p,
193 virtual void PostMessage_MainThreadContinuation(PostMessageResource* p,
196 virtual void OpenManifestEntry_MainThreadContinuation(
197 OpenManifestEntryResource* p,
200 virtual void StreamAsFile_MainThreadContinuation(
201 OpenManifestEntryResource* p,
204 virtual void BitcodeTranslate_MainThreadContinuation(
205 OpenManifestEntryResource* p,
208 virtual void CloseManifestEntry_MainThreadContinuation(
209 CloseManifestEntryResource* cls,
213 nacl::WeakRefAnchor* anchor_; // holds a ref
214 Plugin* plugin_; // value may be copied, but should be used only in
215 // main thread in WeakRef-protected callbacks.
216 const Manifest* manifest_;
217 ServiceRuntime* service_runtime_;
220 std::set<int64_t> quota_files_;
223 nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_;
225 pp::CompletionCallback init_done_cb_;
226 pp::CompletionCallback crash_cb_;
229 // ServiceRuntime abstracts a NativeClient sel_ldr instance.
230 class ServiceRuntime {
232 // TODO(sehr): This class should also implement factory methods, using the
233 // Start method below.
234 ServiceRuntime(Plugin* plugin,
235 const Manifest* manifest,
236 bool should_report_uma,
237 pp::CompletionCallback init_done_cb,
238 pp::CompletionCallback crash_cb);
239 // The destructor terminates the sel_ldr process.
242 // Spawn the sel_ldr instance. On success, returns true.
243 // On failure, returns false and |error_string| is set to something
244 // describing the error.
245 bool StartSelLdr(const SelLdrStartParams& params);
247 // If starting sel_ldr from a background thread, wait for sel_ldr to
249 void WaitForSelLdrStart();
251 // Signal to waiting threads that StartSelLdr is complete.
252 // Done externally, in case external users want to write to shared
253 // memory that is yet to be fenced.
254 void SignalStartSelLdrDone();
256 // Establish an SrpcClient to the sel_ldr instance and load the nexe.
257 // The nexe to be started is passed through |nacl_file_desc|.
258 // On success, returns true. On failure, returns false and |error_string|
259 // is set to something describing the error.
260 bool LoadNexeAndStart(nacl::DescWrapper* nacl_file_desc,
261 ErrorInfo* error_info,
262 const pp::CompletionCallback& crash_cb);
264 // Starts the application channel to the nexe.
265 SrpcClient* SetupAppChannel();
267 bool Log(int severity, const nacl::string& msg);
268 Plugin* plugin() const { return plugin_; }
271 // exit_status is -1 when invalid; when we set it, we will ensure
272 // that it is non-negative (the portion of the exit status from the
273 // nexe that is transferred is the low 8 bits of the argument to the
275 int exit_status(); // const, but grabs mutex etc.
276 void set_exit_status(int exit_status);
278 nacl::string GetCrashLogOutput();
280 // To establish quota callbacks the pnacl coordinator needs to communicate
281 // with the reverse interface.
282 PluginReverseInterface* rev_interface() const { return rev_interface_; }
285 NACL_DISALLOW_COPY_AND_ASSIGN(ServiceRuntime);
286 bool InitCommunication(nacl::DescWrapper* shm, ErrorInfo* error_info);
288 NaClSrpcChannel command_channel_;
290 bool should_report_uma_;
291 nacl::ReverseService* reverse_service_;
292 nacl::scoped_ptr<nacl::SelLdrLauncherBase> subprocess_;
294 nacl::WeakRefAnchor* anchor_;
296 PluginReverseInterface* rev_interface_;
298 // Mutex to protect exit_status_.
299 // Also, in conjunction with cond_ it is used to signal when
300 // StartSelLdr is complete with either success or error.
304 bool start_sel_ldr_done_;
307 } // namespace plugin
309 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_