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"
27 #include "ppapi/native_client/src/trusted/plugin/utility.h"
28 #include "ppapi/utility/completion_callback_factory.h"
48 // Struct of params used by StartSelLdr. Use a struct so that callback
49 // creation templates aren't overwhelmed with too many parameters.
50 struct SelLdrStartParams {
51 SelLdrStartParams(const nacl::string& url,
54 bool enable_dev_interfaces,
55 bool enable_dyncode_syscalls,
56 bool enable_exception_handling,
57 bool enable_crash_throttling)
60 uses_ppapi(uses_ppapi),
61 enable_dev_interfaces(enable_dev_interfaces),
62 enable_dyncode_syscalls(enable_dyncode_syscalls),
63 enable_exception_handling(enable_exception_handling),
64 enable_crash_throttling(enable_crash_throttling) {
69 bool enable_dev_interfaces;
70 bool enable_dyncode_syscalls;
71 bool enable_exception_handling;
72 bool enable_crash_throttling;
75 // Callback resources are essentially our continuation state.
76 struct PostMessageResource {
78 explicit PostMessageResource(std::string msg)
83 struct OpenManifestEntryResource {
85 OpenManifestEntryResource(const std::string& target_url,
86 struct NaClFileInfo* finfo,
92 op_complete_ptr(op_complete) {}
94 struct NaClFileInfo* file_info;
95 ErrorInfo* error_info;
96 bool* op_complete_ptr;
99 struct CloseManifestEntryResource {
101 CloseManifestEntryResource(int32_t desc_to_close,
104 : desc(desc_to_close),
105 op_complete_ptr(op_complete),
106 op_result_ptr(op_result) {}
109 bool* op_complete_ptr;
113 struct QuotaRequest {
115 QuotaRequest(PP_Resource pp_resource,
116 int64_t start_offset,
117 int64_t quota_bytes_requested,
118 int64_t* quota_bytes_granted,
120 : resource(pp_resource),
121 offset(start_offset),
122 bytes_requested(quota_bytes_requested),
123 bytes_granted(quota_bytes_granted),
124 op_complete_ptr(op_complete) { }
126 PP_Resource resource;
128 int64_t bytes_requested;
129 int64_t* bytes_granted;
130 bool* op_complete_ptr;
133 // Do not invoke from the main thread, since the main methods will
134 // invoke CallOnMainThread and then wait on a condvar for the task to
135 // complete: if invoked from the main thread, the main method not
136 // returning (and thus unblocking the main thread) means that the
137 // main-thread continuation methods will never get called, and thus
138 // we'd get a deadlock.
139 class PluginReverseInterface: public nacl::ReverseInterface {
141 PluginReverseInterface(nacl::WeakRefAnchor* anchor,
143 const Manifest* manifest,
144 ServiceRuntime* service_runtime,
145 pp::CompletionCallback init_done_cb,
146 pp::CompletionCallback crash_cb);
148 virtual ~PluginReverseInterface();
152 virtual void DoPostMessage(nacl::string message);
154 virtual void StartupInitializationComplete();
156 virtual bool EnumerateManifestKeys(std::set<nacl::string>* out_keys);
158 virtual bool OpenManifestEntry(nacl::string url_key,
159 struct NaClFileInfo *info);
161 virtual bool CloseManifestEntry(int32_t desc);
163 virtual void ReportCrash();
165 virtual void ReportExitStatus(int exit_status);
167 virtual int64_t RequestQuotaForWrite(nacl::string file_id,
169 int64_t bytes_to_write);
171 void AddQuotaManagedFile(const nacl::string& file_id,
172 const pp::FileIO& file_io);
173 void AddTempQuotaManagedFile(const nacl::string& file_id);
176 virtual void PostMessage_MainThreadContinuation(PostMessageResource* p,
179 virtual void OpenManifestEntry_MainThreadContinuation(
180 OpenManifestEntryResource* p,
183 virtual void StreamAsFile_MainThreadContinuation(
184 OpenManifestEntryResource* p,
187 virtual void CloseManifestEntry_MainThreadContinuation(
188 CloseManifestEntryResource* cls,
192 nacl::WeakRefAnchor* anchor_; // holds a ref
193 Plugin* plugin_; // value may be copied, but should be used only in
194 // main thread in WeakRef-protected callbacks.
195 const Manifest* manifest_;
196 ServiceRuntime* service_runtime_;
199 std::set<int64_t> quota_files_;
202 pp::CompletionCallback init_done_cb_;
203 pp::CompletionCallback crash_cb_;
206 // ServiceRuntime abstracts a NativeClient sel_ldr instance.
207 class ServiceRuntime {
209 // TODO(sehr): This class should also implement factory methods, using the
210 // Start method below.
211 ServiceRuntime(Plugin* plugin,
212 const Manifest* manifest,
213 bool should_report_uma,
214 pp::CompletionCallback init_done_cb,
215 pp::CompletionCallback crash_cb);
216 // The destructor terminates the sel_ldr process.
219 // Spawn the sel_ldr instance.
220 void StartSelLdr(const SelLdrStartParams& params,
221 pp::CompletionCallback callback);
223 // If starting sel_ldr from a background thread, wait for sel_ldr to
225 void WaitForSelLdrStart();
227 // Signal to waiting threads that StartSelLdr is complete.
228 // Done externally, in case external users want to write to shared
229 // memory that is yet to be fenced.
230 void SignalStartSelLdrDone();
232 // Establish an SrpcClient to the sel_ldr instance and load the nexe.
233 // The nexe to be started is passed through |nacl_file_desc|.
234 // On success, returns true. On failure, returns false.
235 bool LoadNexeAndStart(nacl::DescWrapper* nacl_file_desc,
236 const pp::CompletionCallback& crash_cb);
238 // Starts the application channel to the nexe.
239 SrpcClient* SetupAppChannel();
241 bool Log(int severity, const nacl::string& msg);
242 Plugin* plugin() const { return plugin_; }
245 // exit_status is -1 when invalid; when we set it, we will ensure
246 // that it is non-negative (the portion of the exit status from the
247 // nexe that is transferred is the low 8 bits of the argument to the
249 int exit_status(); // const, but grabs mutex etc.
250 void set_exit_status(int exit_status);
252 nacl::string GetCrashLogOutput();
254 // To establish quota callbacks the pnacl coordinator needs to communicate
255 // with the reverse interface.
256 PluginReverseInterface* rev_interface() const { return rev_interface_; }
259 NACL_DISALLOW_COPY_AND_ASSIGN(ServiceRuntime);
260 bool LoadModule(nacl::DescWrapper* shm, ErrorInfo* error_info);
261 bool InitReverseService(ErrorInfo* error_info);
262 bool StartModule(ErrorInfo* error_info);
263 void StartSelLdrContinuation(int32_t pp_error,
264 pp::CompletionCallback callback);
266 NaClSrpcChannel command_channel_;
268 bool main_service_runtime_;
269 nacl::ReverseService* reverse_service_;
270 nacl::scoped_ptr<nacl::SelLdrLauncherBase> subprocess_;
272 nacl::WeakRefAnchor* anchor_;
274 PluginReverseInterface* rev_interface_;
276 // Mutex to protect exit_status_.
277 // Also, in conjunction with cond_ it is used to signal when
278 // StartSelLdr is complete with either success or error.
282 bool start_sel_ldr_done_;
284 PP_Var start_sel_ldr_error_message_;
285 pp::CompletionCallbackFactory<ServiceRuntime> callback_factory_;
288 } // namespace plugin
290 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_