- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / native_client / src / trusted / plugin / service_runtime.h
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 <set>
15
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"
25
26 #include "ppapi/cpp/completion_callback.h"
27
28 #include "ppapi/native_client/src/trusted/plugin/utility.h"
29
30 struct NaClFileInfo;
31
32 namespace nacl {
33 class DescWrapper;
34 }  // namespace
35
36 namespace pp {
37 class FileIO;
38 }  // namespace
39
40 namespace plugin {
41
42 class ErrorInfo;
43 class Manifest;
44 class Plugin;
45 class PnaclCoordinator;
46 class SrpcClient;
47 class ServiceRuntime;
48
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,
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       : url(url),
61         error_info(error_info),
62         uses_irt(uses_irt),
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) {
68   }
69   nacl::string url;
70   ErrorInfo* error_info;
71   bool uses_irt;
72   bool uses_ppapi;
73   bool enable_dev_interfaces;
74   bool enable_dyncode_syscalls;
75   bool enable_exception_handling;
76   bool enable_crash_throttling;
77 };
78
79 // Callback resources are essentially our continuation state.
80
81 struct LogToJavaScriptConsoleResource {
82  public:
83   explicit LogToJavaScriptConsoleResource(std::string msg)
84       : message(msg) {}
85   std::string message;
86 };
87
88 struct PostMessageResource {
89  public:
90   explicit PostMessageResource(std::string msg)
91       : message(msg) {}
92   std::string message;
93 };
94
95 struct OpenManifestEntryResource {
96  public:
97   OpenManifestEntryResource(const std::string& target_url,
98                             struct NaClFileInfo* finfo,
99                             ErrorInfo* infop,
100                             bool* op_complete)
101       : url(target_url),
102         file_info(finfo),
103         error_info(infop),
104         op_complete_ptr(op_complete) {}
105   std::string url;
106   struct NaClFileInfo* file_info;
107   ErrorInfo* error_info;
108   bool* op_complete_ptr;
109 };
110
111 struct CloseManifestEntryResource {
112  public:
113   CloseManifestEntryResource(int32_t desc_to_close,
114                              bool* op_complete,
115                              bool* op_result)
116       : desc(desc_to_close),
117         op_complete_ptr(op_complete),
118         op_result_ptr(op_result) {}
119
120   int32_t desc;
121   bool* op_complete_ptr;
122   bool* op_result_ptr;
123 };
124
125 struct QuotaRequest {
126  public:
127   QuotaRequest(PP_Resource pp_resource,
128                int64_t start_offset,
129                int64_t quota_bytes_requested,
130                int64_t* quota_bytes_granted,
131                bool* op_complete)
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) { }
137
138   PP_Resource resource;
139   int64_t offset;
140   int64_t bytes_requested;
141   int64_t* bytes_granted;
142   bool* op_complete_ptr;
143 };
144
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 {
152  public:
153   PluginReverseInterface(nacl::WeakRefAnchor* anchor,
154                          Plugin* plugin,
155                          const Manifest* manifest,
156                          ServiceRuntime* service_runtime,
157                          pp::CompletionCallback init_done_cb,
158                          pp::CompletionCallback crash_cb);
159
160   virtual ~PluginReverseInterface();
161
162   void ShutDown();
163
164   virtual void Log(nacl::string message);
165
166   virtual void DoPostMessage(nacl::string message);
167
168   virtual void StartupInitializationComplete();
169
170   virtual bool EnumerateManifestKeys(std::set<nacl::string>* out_keys);
171
172   virtual bool OpenManifestEntry(nacl::string url_key,
173                                  struct NaClFileInfo *info);
174
175   virtual bool CloseManifestEntry(int32_t desc);
176
177   virtual void ReportCrash();
178
179   virtual void ReportExitStatus(int exit_status);
180
181   virtual int64_t RequestQuotaForWrite(nacl::string file_id,
182                                        int64_t offset,
183                                        int64_t bytes_to_write);
184
185   void AddQuotaManagedFile(const nacl::string& file_id,
186                            const pp::FileIO& file_io);
187   void AddTempQuotaManagedFile(const nacl::string& file_id);
188
189  protected:
190   virtual void Log_MainThreadContinuation(LogToJavaScriptConsoleResource* p,
191                                           int32_t err);
192
193   virtual void PostMessage_MainThreadContinuation(PostMessageResource* p,
194                                                   int32_t err);
195
196   virtual void OpenManifestEntry_MainThreadContinuation(
197       OpenManifestEntryResource* p,
198       int32_t err);
199
200   virtual void StreamAsFile_MainThreadContinuation(
201       OpenManifestEntryResource* p,
202       int32_t result);
203
204   virtual void BitcodeTranslate_MainThreadContinuation(
205       OpenManifestEntryResource* p,
206       int32_t result);
207
208   virtual void CloseManifestEntry_MainThreadContinuation(
209       CloseManifestEntryResource* cls,
210       int32_t err);
211
212  private:
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_;
218   NaClMutex mu_;
219   NaClCondVar cv_;
220   std::set<int64_t> quota_files_;
221   bool shutting_down_;
222
223   nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_;
224
225   pp::CompletionCallback init_done_cb_;
226   pp::CompletionCallback crash_cb_;
227 };
228
229 //  ServiceRuntime abstracts a NativeClient sel_ldr instance.
230 class ServiceRuntime {
231  public:
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.
240   ~ServiceRuntime();
241
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);
246
247   // If starting sel_ldr from a background thread, wait for sel_ldr to
248   // actually start.
249   void WaitForSelLdrStart();
250
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();
255
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);
263
264   // Starts the application channel to the nexe.
265   SrpcClient* SetupAppChannel();
266
267   bool Log(int severity, const nacl::string& msg);
268   Plugin* plugin() const { return plugin_; }
269   void Shutdown();
270
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
274   // exit syscall).
275   int exit_status();  // const, but grabs mutex etc.
276   void set_exit_status(int exit_status);
277
278   nacl::string GetCrashLogOutput();
279
280   // To establish quota callbacks the pnacl coordinator needs to communicate
281   // with the reverse interface.
282   PluginReverseInterface* rev_interface() const { return rev_interface_; }
283
284  private:
285   NACL_DISALLOW_COPY_AND_ASSIGN(ServiceRuntime);
286   bool InitCommunication(nacl::DescWrapper* shm, ErrorInfo* error_info);
287
288   NaClSrpcChannel command_channel_;
289   Plugin* plugin_;
290   bool should_report_uma_;
291   nacl::ReverseService* reverse_service_;
292   nacl::scoped_ptr<nacl::SelLdrLauncherBase> subprocess_;
293
294   nacl::WeakRefAnchor* anchor_;
295
296   PluginReverseInterface* rev_interface_;
297
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.
301   NaClMutex mu_;
302   NaClCondVar cond_;
303   int exit_status_;
304   bool start_sel_ldr_done_;
305 };
306
307 }  // namespace plugin
308
309 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_