Upstream version 9.38.198.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
29 struct NaClFileInfo;
30
31 namespace nacl {
32 class DescWrapper;
33 }  // namespace
34
35 namespace plugin {
36
37 class ErrorInfo;
38 class Plugin;
39 class SelLdrLauncherChrome;
40 class SrpcClient;
41 class ServiceRuntime;
42
43 // Struct of params used by StartSelLdr.  Use a struct so that callback
44 // creation templates aren't overwhelmed with too many parameters.
45 struct SelLdrStartParams {
46   SelLdrStartParams(const nacl::string& url,
47                     const PP_NaClFileInfo& file_info,
48                     bool uses_irt,
49                     bool uses_ppapi,
50                     bool enable_dyncode_syscalls,
51                     bool enable_exception_handling,
52                     bool enable_crash_throttling)
53       : url(url),
54         file_info(file_info),
55         uses_irt(uses_irt),
56         uses_ppapi(uses_ppapi),
57         enable_dyncode_syscalls(enable_dyncode_syscalls),
58         enable_exception_handling(enable_exception_handling),
59         enable_crash_throttling(enable_crash_throttling) {
60   }
61   nacl::string url;
62   PP_NaClFileInfo file_info;
63   bool uses_irt;
64   bool uses_ppapi;
65   bool enable_dev_interfaces;
66   bool enable_dyncode_syscalls;
67   bool enable_exception_handling;
68   bool enable_crash_throttling;
69 };
70
71 // Callback resources are essentially our continuation state.
72 struct OpenManifestEntryResource {
73  public:
74   OpenManifestEntryResource(const std::string& target_url,
75                             struct NaClFileInfo* finfo,
76                             bool* op_complete)
77       : url(target_url),
78         file_info(finfo),
79         op_complete_ptr(op_complete) {}
80   ~OpenManifestEntryResource();
81
82   std::string url;
83   struct NaClFileInfo* file_info;
84   PP_NaClFileInfo pp_file_info;
85   bool* op_complete_ptr;
86 };
87
88 // Do not invoke from the main thread, since the main methods will
89 // invoke CallOnMainThread and then wait on a condvar for the task to
90 // complete: if invoked from the main thread, the main method not
91 // returning (and thus unblocking the main thread) means that the
92 // main-thread continuation methods will never get called, and thus
93 // we'd get a deadlock.
94 class PluginReverseInterface: public nacl::ReverseInterface {
95  public:
96   PluginReverseInterface(nacl::WeakRefAnchor* anchor,
97                          PP_Instance pp_instance,
98                          ServiceRuntime* service_runtime,
99                          pp::CompletionCallback init_done_cb,
100                          pp::CompletionCallback crash_cb);
101
102   virtual ~PluginReverseInterface();
103
104   void ShutDown();
105
106   virtual void DoPostMessage(nacl::string message);
107
108   virtual void StartupInitializationComplete();
109
110   virtual bool OpenManifestEntry(nacl::string url_key,
111                                  struct NaClFileInfo *info);
112
113   virtual void ReportCrash();
114
115   virtual void ReportExitStatus(int exit_status);
116
117   // TODO(teravest): Remove this method once it's gone from
118   // nacl::ReverseInterface.
119   virtual int64_t RequestQuotaForWrite(nacl::string file_id,
120                                        int64_t offset,
121                                        int64_t bytes_to_write);
122
123  protected:
124   virtual void OpenManifestEntry_MainThreadContinuation(
125       OpenManifestEntryResource* p,
126       int32_t err);
127
128   virtual void StreamAsFile_MainThreadContinuation(
129       OpenManifestEntryResource* p,
130       int32_t result);
131
132  private:
133   nacl::WeakRefAnchor* anchor_;  // holds a ref
134   // Should be used only in main thread in WeakRef-protected callbacks.
135   PP_Instance pp_instance_;
136   ServiceRuntime* service_runtime_;
137   NaClMutex mu_;
138   NaClCondVar cv_;
139   bool shutting_down_;
140
141   pp::CompletionCallback init_done_cb_;
142   pp::CompletionCallback crash_cb_;
143 };
144
145 //  ServiceRuntime abstracts a NativeClient sel_ldr instance.
146 class ServiceRuntime {
147  public:
148   // TODO(sehr): This class should also implement factory methods, using the
149   // Start method below.
150   ServiceRuntime(Plugin* plugin,
151                  PP_Instance pp_instance,
152                  bool main_service_runtime,
153                  bool uses_nonsfi_mode,
154                  pp::CompletionCallback init_done_cb,
155                  pp::CompletionCallback crash_cb);
156   // The destructor terminates the sel_ldr process.
157   ~ServiceRuntime();
158
159   // Spawn the sel_ldr instance.
160   void StartSelLdr(const SelLdrStartParams& params,
161                    pp::CompletionCallback callback);
162
163   // If starting sel_ldr from a background thread, wait for sel_ldr to
164   // actually start. Returns |false| if timed out waiting for the process
165   // to start. Otherwise, returns |true| if StartSelLdr is complete
166   // (either successfully or unsuccessfully).
167   bool WaitForSelLdrStart();
168
169   // Signal to waiting threads that StartSelLdr is complete (either
170   // successfully or unsuccessfully).
171   void SignalStartSelLdrDone();
172
173   // If starting the nexe from a background thread, wait for the nexe to
174   // actually start. Returns |true| is the nexe started successfully.
175   bool WaitForNexeStart();
176
177   // Signal to waiting threads that LoadNexeAndStart is complete (either
178   // successfully or unsuccessfully).
179   void SignalNexeStarted(bool ok);
180
181   // Establish an SrpcClient to the sel_ldr instance and start the nexe.
182   // This function must be called on the main thread.
183   // This function must only be called once.
184   void StartNexe();
185
186   // Starts the application channel to the nexe.
187   SrpcClient* SetupAppChannel();
188
189   bool RemoteLog(int severity, const nacl::string& msg);
190   Plugin* plugin() const { return plugin_; }
191   void Shutdown();
192
193   // exit_status is -1 when invalid; when we set it, we will ensure
194   // that it is non-negative (the portion of the exit status from the
195   // nexe that is transferred is the low 8 bits of the argument to the
196   // exit syscall).
197   int exit_status();  // const, but grabs mutex etc.
198   void set_exit_status(int exit_status);
199
200   nacl::string GetCrashLogOutput();
201
202   bool main_service_runtime() const { return main_service_runtime_; }
203
204  private:
205   NACL_DISALLOW_COPY_AND_ASSIGN(ServiceRuntime);
206   bool StartNexeInternal();
207
208   bool SetupCommandChannel();
209   bool InitReverseService();
210   bool StartModule();
211   void ReapLogs();
212
213   void ReportLoadError(const ErrorInfo& error_info);
214
215   NaClSrpcChannel command_channel_;
216   Plugin* plugin_;
217   PP_Instance pp_instance_;
218   bool main_service_runtime_;
219   bool uses_nonsfi_mode_;
220   nacl::ReverseService* reverse_service_;
221   nacl::scoped_ptr<SelLdrLauncherChrome> subprocess_;
222
223   nacl::WeakRefAnchor* anchor_;
224
225   PluginReverseInterface* rev_interface_;
226
227   // Mutex and CondVar to protect start_sel_ldr_done_ and nexe_started_.
228   NaClMutex mu_;
229   NaClCondVar cond_;
230   bool start_sel_ldr_done_;
231   bool start_nexe_done_;
232   bool nexe_started_ok_;
233
234   NaClHandle bootstrap_channel_;
235 };
236
237 }  // namespace plugin
238
239 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_