Upstream version 5.34.104.0
[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 #include "ppapi/native_client/src/trusted/plugin/utility.h"
28 #include "ppapi/utility/completion_callback_factory.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 SrpcClient;
46 class ServiceRuntime;
47
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,
52                     bool uses_irt,
53                     bool uses_ppapi,
54                     bool enable_dev_interfaces,
55                     bool enable_dyncode_syscalls,
56                     bool enable_exception_handling,
57                     bool enable_crash_throttling)
58       : url(url),
59         uses_irt(uses_irt),
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) {
65   }
66   nacl::string url;
67   bool uses_irt;
68   bool uses_ppapi;
69   bool enable_dev_interfaces;
70   bool enable_dyncode_syscalls;
71   bool enable_exception_handling;
72   bool enable_crash_throttling;
73 };
74
75 // Callback resources are essentially our continuation state.
76 struct PostMessageResource {
77  public:
78   explicit PostMessageResource(std::string msg)
79       : message(msg) {}
80   std::string message;
81 };
82
83 struct OpenManifestEntryResource {
84  public:
85   OpenManifestEntryResource(const std::string& target_url,
86                             struct NaClFileInfo* finfo,
87                             ErrorInfo* infop,
88                             bool* op_complete)
89       : url(target_url),
90         file_info(finfo),
91         error_info(infop),
92         op_complete_ptr(op_complete) {}
93   std::string url;
94   struct NaClFileInfo* file_info;
95   ErrorInfo* error_info;
96   bool* op_complete_ptr;
97 };
98
99 struct CloseManifestEntryResource {
100  public:
101   CloseManifestEntryResource(int32_t desc_to_close,
102                              bool* op_complete,
103                              bool* op_result)
104       : desc(desc_to_close),
105         op_complete_ptr(op_complete),
106         op_result_ptr(op_result) {}
107
108   int32_t desc;
109   bool* op_complete_ptr;
110   bool* op_result_ptr;
111 };
112
113 struct QuotaRequest {
114  public:
115   QuotaRequest(PP_Resource pp_resource,
116                int64_t start_offset,
117                int64_t quota_bytes_requested,
118                int64_t* quota_bytes_granted,
119                bool* op_complete)
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) { }
125
126   PP_Resource resource;
127   int64_t offset;
128   int64_t bytes_requested;
129   int64_t* bytes_granted;
130   bool* op_complete_ptr;
131 };
132
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 {
140  public:
141   PluginReverseInterface(nacl::WeakRefAnchor* anchor,
142                          Plugin* plugin,
143                          const Manifest* manifest,
144                          ServiceRuntime* service_runtime,
145                          pp::CompletionCallback init_done_cb,
146                          pp::CompletionCallback crash_cb);
147
148   virtual ~PluginReverseInterface();
149
150   void ShutDown();
151
152   virtual void DoPostMessage(nacl::string message);
153
154   virtual void StartupInitializationComplete();
155
156   virtual bool EnumerateManifestKeys(std::set<nacl::string>* out_keys);
157
158   virtual bool OpenManifestEntry(nacl::string url_key,
159                                  struct NaClFileInfo *info);
160
161   virtual bool CloseManifestEntry(int32_t desc);
162
163   virtual void ReportCrash();
164
165   virtual void ReportExitStatus(int exit_status);
166
167   virtual int64_t RequestQuotaForWrite(nacl::string file_id,
168                                        int64_t offset,
169                                        int64_t bytes_to_write);
170
171   void AddQuotaManagedFile(const nacl::string& file_id,
172                            const pp::FileIO& file_io);
173   void AddTempQuotaManagedFile(const nacl::string& file_id);
174
175  protected:
176   virtual void PostMessage_MainThreadContinuation(PostMessageResource* p,
177                                                   int32_t err);
178
179   virtual void OpenManifestEntry_MainThreadContinuation(
180       OpenManifestEntryResource* p,
181       int32_t err);
182
183   virtual void StreamAsFile_MainThreadContinuation(
184       OpenManifestEntryResource* p,
185       int32_t result);
186
187   virtual void CloseManifestEntry_MainThreadContinuation(
188       CloseManifestEntryResource* cls,
189       int32_t err);
190
191  private:
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_;
197   NaClMutex mu_;
198   NaClCondVar cv_;
199   std::set<int64_t> quota_files_;
200   bool shutting_down_;
201
202   pp::CompletionCallback init_done_cb_;
203   pp::CompletionCallback crash_cb_;
204 };
205
206 //  ServiceRuntime abstracts a NativeClient sel_ldr instance.
207 class ServiceRuntime {
208  public:
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.
217   ~ServiceRuntime();
218
219   // Spawn the sel_ldr instance.
220   void StartSelLdr(const SelLdrStartParams& params,
221                    pp::CompletionCallback callback);
222
223   // If starting sel_ldr from a background thread, wait for sel_ldr to
224   // actually start.
225   void WaitForSelLdrStart();
226
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();
231
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);
237
238   // Starts the application channel to the nexe.
239   SrpcClient* SetupAppChannel();
240
241   bool Log(int severity, const nacl::string& msg);
242   Plugin* plugin() const { return plugin_; }
243   void Shutdown();
244
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
248   // exit syscall).
249   int exit_status();  // const, but grabs mutex etc.
250   void set_exit_status(int exit_status);
251
252   nacl::string GetCrashLogOutput();
253
254   // To establish quota callbacks the pnacl coordinator needs to communicate
255   // with the reverse interface.
256   PluginReverseInterface* rev_interface() const { return rev_interface_; }
257
258  private:
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);
265
266   NaClSrpcChannel command_channel_;
267   Plugin* plugin_;
268   bool main_service_runtime_;
269   nacl::ReverseService* reverse_service_;
270   nacl::scoped_ptr<nacl::SelLdrLauncherBase> subprocess_;
271
272   nacl::WeakRefAnchor* anchor_;
273
274   PluginReverseInterface* rev_interface_;
275
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.
279   NaClMutex mu_;
280   NaClCondVar cond_;
281   int exit_status_;
282   bool start_sel_ldr_done_;
283
284   PP_Var start_sel_ldr_error_message_;
285   pp::CompletionCallbackFactory<ServiceRuntime> callback_factory_;
286 };
287
288 }  // namespace plugin
289
290 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_