Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h

Issue 8786005: Move command line processing out of coordinator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ 5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_
6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ 6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_
7 7
8 #include <set> 8 #include <set>
9 #include <map> 9 #include <map>
10 #include <vector> 10 #include <vector>
11 11
12 #include "native_client/src/include/nacl_macros.h" 12 #include "native_client/src/include/nacl_macros.h"
13 #include "native_client/src/include/nacl_string.h" 13 #include "native_client/src/include/nacl_string.h"
14 #include "native_client/src/shared/platform/nacl_sync_checked.h" 14 #include "native_client/src/shared/platform/nacl_sync_checked.h"
15 #include "native_client/src/shared/platform/nacl_sync_raii.h"
15 #include "native_client/src/shared/platform/nacl_threads.h" 16 #include "native_client/src/shared/platform/nacl_threads.h"
16 #include "native_client/src/shared/srpc/nacl_srpc.h" 17 #include "native_client/src/shared/srpc/nacl_srpc.h"
18 #include "native_client/src/trusted/desc/nacl_desc_rng.h"
17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" 19 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
18 #include "native_client/src/trusted/plugin/delayed_callback.h" 20 #include "native_client/src/trusted/plugin/delayed_callback.h"
19 #include "native_client/src/trusted/plugin/nacl_subprocess.h" 21 #include "native_client/src/trusted/plugin/nacl_subprocess.h"
20 #include "native_client/src/trusted/plugin/plugin_error.h" 22 #include "native_client/src/trusted/plugin/plugin_error.h"
21 #include "native_client/src/trusted/plugin/pnacl_resources.h" 23 #include "native_client/src/trusted/plugin/pnacl_resources.h"
22 24
25 #include "ppapi/c/pp_file_info.h"
23 #include "ppapi/cpp/completion_callback.h" 26 #include "ppapi/cpp/completion_callback.h"
27 #include "ppapi/cpp/file_io.h"
28 #include "ppapi/cpp/file_ref.h"
29 #include "ppapi/cpp/file_system.h"
24 30
25 struct NaClMutex; 31 struct NaClMutex;
32 struct PPB_FileIOTrusted;
26 33
27 namespace plugin { 34 namespace plugin {
28 35
29 class Plugin; 36 class Plugin;
30 class PnaclCoordinator; 37 class PnaclCoordinator;
31 38
32 struct PnaclTranslationUnit { 39 // Translation creates two temporary files. The first temporary file holds
33 PnaclTranslationUnit(PnaclCoordinator* coord) 40 // the object file created by llc. The second holds the nexe produced by
34 : coordinator(coord), 41 // the linker. Both of these temporary files are used to both write and
35 obj_len(-1), 42 // read according to the following matrix:
36 is_shared_library(false), 43 //
37 soname(""), 44 // PnaclCoordinator::obj_file_:
38 lib_dependencies("") { 45 // written by: llc (passed in explicitly through SRPC)
46 // read by: ld (returned via lookup service from SRPC)
47 // PnaclCoordinator::nexe_file_:
48 // written by: lc (passed in explicitly through SRPC)
49 // read by: sel_ldr (passed in explicitly to command channel)
50 //
51
52 // PnaclFileDescPair represents a file used as a temporary between stages in
53 // translation. It is created in the local temporary file system of the page
54 // being processed. The name of the temporary file is a random 32-character
55 // hex string. Because both reading and writing are necessary, two I/O objects
56 // for the file are opened.
57 class PnaclFileDescPair {
58 public:
59 PnaclFileDescPair(Plugin* plugin,
60 pp::FileSystem* file_system,
61 PnaclCoordinator* coordinator);
62 ~PnaclFileDescPair();
63 // Opens a pair of file IO objects referring to a randomly named file in
64 // file_system_. One IO is for writing the file and another for reading it.
65 void Open(const pp::CompletionCallback& cb);
66 // Accessors.
67 // The nacl::DescWrapper* for the writeable version of the file.
68 nacl::DescWrapper* write_wrapper() { return write_wrapper_.get(); }
69 // The nacl::DescWrapper* for the read-only version of the file.
70 nacl::DescWrapper* read_wrapper() { return read_wrapper_.get(); }
71
72 private:
73 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclFileDescPair);
74
75 // Gets the POSIX file descriptor for a resource.
76 int32_t GetFD(int32_t pp_error,
77 const pp::Resource& resource,
78 bool is_writable);
79 // Called when the writable file IO was opened.
80 void WriteFileDidOpen(int32_t pp_error);
81 // Called when the readable file IO was opened.
82 void ReadFileDidOpen(int32_t pp_error);
83
84 Plugin* plugin_;
85 pp::FileSystem* file_system_;
86 PnaclCoordinator* coordinator_;
87 const PPB_FileIOTrusted* file_io_trusted_;
88 pp::CompletionCallbackFactory<PnaclFileDescPair> callback_factory_;
89 nacl::string filename_;
90 // The PPAPI and wrapper state for the writeable file.
91 nacl::scoped_ptr<pp::FileRef> write_ref_;
92 nacl::scoped_ptr<pp::FileIO> write_io_;
93 nacl::scoped_ptr<nacl::DescWrapper> write_wrapper_;
94 // The PPAPI and wrapper state for the read-only file.
95 nacl::scoped_ptr<pp::FileRef> read_ref_;
96 nacl::scoped_ptr<pp::FileIO> read_io_;
97 nacl::scoped_ptr<nacl::DescWrapper> read_wrapper_;
98 // The callback invoked when both file I/O objects are created.
99 pp::CompletionCallback done_callback_;
100 // Random number generator used to create filenames.
101 struct NaClDescRng rng_desc_;
102 };
103
104 // A thread safe reference counting class Needed for CompletionCallbackFactory
105 // in PnaclCoordinator.
106 class PnaclRefCount {
107 public:
108 PnaclRefCount() : ref_(0) { NaClXMutexCtor(&mu_); }
109 ~PnaclRefCount() { NaClMutexDtor(&mu_); }
110 int32_t AddRef() {
111 nacl::MutexLocker ml(&mu_);
112 return ++ref_;
39 } 113 }
40 // Punch hole in abstraction. 114 int32_t Release() {
41 PnaclCoordinator* coordinator; 115 nacl::MutexLocker ml(&mu_);
42 116 return --ref_;
43 // Borrowed reference which must outlive the thread. 117 }
44 nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper; 118
45 119 private:
46 // Object file produced by translator and consumed by the linker. 120 int32_t ref_;
47 nacl::scoped_ptr<nacl::DescWrapper> obj_wrapper; 121 struct NaClMutex mu_;
48 int32_t obj_len;
49
50 // Information extracted from the pexe that is needed by the linker.
51 bool is_shared_library;
52 nacl::string soname;
53 nacl::string lib_dependencies;
54
55 // The translated user nexe file.
56 nacl::scoped_ptr<nacl::DescWrapper> nexe_wrapper;
57
58 // Callbacks to run when tasks or completed or an error has occurred.
59 pp::CompletionCallback translate_done_cb;
60 pp::CompletionCallback link_done_cb;
61
62 ErrorInfo error_info;
63 }; 122 };
64 123
65 124 // A class invoked by Plugin to handle PNaCl client-side translation.
66 typedef std::pair<nacl::string, pp::CompletionCallback> url_callback_pair;
67
68 // A class that handles PNaCl client-side translation.
69 // Usage: 125 // Usage:
70 // (1) Initialize(); 126 // (1) Invoke the factory method, e.g.,
71 // (2) BitcodeToNative(bitcode, ..., finish_callback); 127 // PnaclCoordinator* coord = BitcodeToNative(plugin,
72 // (3) After finish_callback runs, do: 128 // "http://foo.com/my.pexe",
73 // fd = ReleaseTranslatedFD(); 129 // TranslateNotifyCallback);
74 // (4) go ahead and load the nexe from "fd" 130 // (2) TranslateNotifyCallback gets invoked when translation is complete.
75 // (5) delete 131 // If the translation was successful, the pp_error argument is PP_OK.
132 // Other values indicate errors.
133 // (3) After finish_callback runs, get the file descriptor of the translated
134 // nexe, e.g.,
135 // fd = coord->ReleaseTranslatedFD();
136 // (4) Load the nexe from "fd".
137 // (5) delete coord.
138 //
139 // Translation proceeds in two steps:
140 // (1) llc translates the bitcode in pexe_url_ to an object in obj_file_.
141 // (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_.
142 //
143 // The coordinator proceeds through several states. They are
144 // LOAD_TRANSLATOR_BINARIES
145 // Complete when ResourcesDidLoad is invoked.
146 // OPEN_LOCAL_FILE_SYSTEM
147 // Complete when FileSystemDidOpen is invoked.
148 // OPEN_TMP_FOP_LLC_TO_LD_COMMUNICATION
149 // Complete when ObjectPairDidOpen is invoked.
150 // OPEN_TMP_FOR_LD_TO_SEL_LDR_COMMUNICATION
151 // Complete when NexePairDidOpen is invoked.
152 // PREPARE_PEXE_FOR_STREAMING
153 // Complete when RunTranslate is invoked.
154 // START_LD_AND_LLC_SUBPROCESS_AND_INITIATE_TRANSLATION
155 // Complete when RunTranslate returns.
156 // TRANSLATION_COMPLETE
157 // Complete when TranslateFinished is invoked.
158 //
159 // It should be noted that at the moment we are not properly freeing the
160 // PPAPI resources used for the temporary files used in translation. Until
161 // that is fixed, (4) and (5) should be done in that order.
162 // TODO(sehr): Fix freeing of temporary files.
76 class PnaclCoordinator { 163 class PnaclCoordinator {
77 public: 164 public:
78 PnaclCoordinator()
79 : plugin_(NULL),
80 translate_notify_callback_(pp::BlockUntilComplete()),
81 llc_subprocess_(NULL),
82 ld_subprocess_(NULL),
83 subprocesses_should_die_(false) {
84 NaClXMutexCtor(&subprocess_mu_);
85 }
86
87 virtual ~PnaclCoordinator(); 165 virtual ~PnaclCoordinator();
88 166
89 // Initialize() can only be called once during the lifetime of this instance. 167 // The factory method for translations.
90 void Initialize(Plugin* instance); 168 static PnaclCoordinator* BitcodeToNative(
91 169 Plugin* plugin,
92 void BitcodeToNative(const nacl::string& pexe_url, 170 const nacl::string& pexe_url,
93 const pp::CompletionCallback& finish_callback); 171 const pp::CompletionCallback& translate_notify_callback);
94 172
95 // Call this to take ownership of the FD of the translated nexe after 173 // Call this to take ownership of the FD of the translated nexe after
96 // BitcodeToNative has completed (and the finish_callback called). 174 // BitcodeToNative has completed (and the finish_callback called).
97 nacl::DescWrapper* ReleaseTranslatedFD() { 175 nacl::DescWrapper* ReleaseTranslatedFD() { return translated_fd_.release(); }
98 return translated_fd_.release(); 176
99 } 177 // Looks up a file descriptor for an url that was already downloaded.
100 178 // This is used for getting the descriptor for llc and ld nexes as well
179 // as the libraries and object files used by the linker.
101 int32_t GetLoadedFileDesc(int32_t pp_error, 180 int32_t GetLoadedFileDesc(int32_t pp_error,
102 const nacl::string& url, 181 const nacl::string& url,
103 const nacl::string& component); 182 const nacl::string& component);
104 183
105 // Run when faced with a PPAPI error condition. It brings control back to the
106 // plugin by invoking the |translate_notify_callback_|.
107 void PnaclPpapiError(int32_t pp_error);
108 // Run |translate_notify_callback_| with an error condition that is not 184 // Run |translate_notify_callback_| with an error condition that is not
109 // PPAPI specific. 185 // PPAPI specific.
110 void PnaclNonPpapiError(); 186 void ReportNonPpapiError(const nacl::string& message);
111 // Wrapper for Plugin ReportLoadAbort. 187 // Run when faced with a PPAPI error condition. Bring control back to the
112 void ReportLoadAbort(); 188 // plugin by invoking the |translate_notify_callback_|.
113 // Wrapper for Plugin ReportLoadError. 189 void ReportPpapiError(int32_t pp_error, const nacl::string& message);
114 void ReportLoadError(const ErrorInfo& error); 190 void ReportPpapiError(int32_t pp_error);
115
116 // Accessors for use by helper threads.
117 nacl::string resource_base_url() const { return resource_base_url_; }
118 Plugin* plugin() const { return plugin_; }
119 nacl::string llc_url() const { return llc_url_; }
120 NaClSubprocess* llc_subprocess() const { return llc_subprocess_; }
121 bool StartLlcSubProcess();
122 nacl::string ld_url() const { return ld_url_; }
123 NaClSubprocess* ld_subprocess() const { return ld_subprocess_; }
124 bool StartLdSubProcess();
125 bool SubprocessesShouldDie();
126 void SetSubprocessesShouldDie(bool subprocesses_should_die);
127 PnaclResources* resources() const { return resources_.get(); }
128
129 protected:
130
131 // Callbacks for when various files, etc. have been downloaded.
132 void ResourcesDidLoad(int32_t pp_error,
133 const nacl::string& url,
134 PnaclTranslationUnit* translation_unit);
135
136 // Callbacks for compute-based translation steps.
137 void RunTranslate(int32_t pp_error,
138 const nacl::string& url,
139 PnaclTranslationUnit* translation_unit);
140 void RunLink(int32_t pp_error, PnaclTranslationUnit* translation_unit);
141
142 // Pnacl translation completed normally.
143 void PnaclDidFinish(int32_t pp_error, PnaclTranslationUnit* translation_unit);
144 191
145 private: 192 private:
146 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); 193 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator);
147 194
195 // BitcodeToNative is the factory method for PnaclCoordinators.
196 // Therefore the constructor is private.
197 PnaclCoordinator(Plugin* plugin,
198 const nacl::string& pexe_url,
199 const pp::CompletionCallback& translate_notify_callback,
200 const nacl::string& resource_base_url);
201
202 // Callback for when llc and ld have been downloaded.
203 // This is the first callback invoked in response to BitcodeToNative.
204 void ResourcesDidLoad(int32_t pp_error);
205
206 // Callbacks for temporary file related stages.
207 // They are invoked from ResourcesDidLoad and proceed in declaration order.
208 // Invoked when the temporary file system is successfully opened in PPAPI.
209 void FileSystemDidOpen(int32_t pp_error);
210 // Invoked when the obj_file_ temporary file I/O pair is created.
211 void ObjectPairDidOpen(int32_t pp_error);
212 // Invoked when the nexe_file_ temporary file I/O pair is created.
213 void NexePairDidOpen(int32_t pp_error);
214
215 // Once llc and ld nexes have been loaded and the two temporary files have
216 // been created, this starts the translation. Translation starts two
217 // subprocesses, one for llc and one for ld.
218 void RunTranslate(int32_t pp_error);
219 // Starts an individual llc or ld subprocess used for translation.
220 NaClSubprocess* StartSubprocess(const nacl::string& url);
221 // PnaclCoordinator creates a helper thread to allow translations to be
222 // invoked via SRPC. This is the helper thread function for translation.
223 static void WINAPI DoTranslateThread(void* arg);
224 // Returns true if a the translate thread and subprocesses should stop.
225 bool SubprocessesShouldDie();
226 // Signal the translate thread and subprocesses that they should stop.
227 void SetSubprocessesShouldDie(bool subprocesses_should_die);
228 // Signal that Pnacl translation completed normally.
229 void TranslateFinished(int32_t pp_error);
230 // Signal that Pnacl translation failed, from the translation thread only.
231 void TranslateFailed(const nacl::string& error_string);
232
233 // Support for file lookups needed for ld.
234 // TODO(sehr): remove this when file lookup is through ReverseService.
235 // Invoked on the main thread on behalf of the lookup service to start
236 // loading a particular URL.
237 void LoadOneFile(int32_t pp_error,
238 const nacl::string& url,
239 nacl::DescWrapper** wrapper,
240 pp::CompletionCallback& done_cb);
241 // Invoked by the renderer when the file was loaded.
242 void DidLoadFile(int32_t pp_error,
243 const nacl::string& full_url,
244 nacl::DescWrapper** wrapper,
245 pp::CompletionCallback& done_cb);
246 // Signals the waiting lookup service to resume.
247 void ResumeLookup(int32_t pp_error);
248
249 // The plugin owning the nexe for which we are doing translation.
148 Plugin* plugin_; 250 Plugin* plugin_;
251
149 pp::CompletionCallback translate_notify_callback_; 252 pp::CompletionCallback translate_notify_callback_;
150 pp::CompletionCallbackFactory<PnaclCoordinator> callback_factory_; 253 // PnaclRefCount is only needed to support file lookups.
254 // TODO(sehr): remove this when file lookup is through ReverseService.
255 pp::CompletionCallbackFactory<PnaclCoordinator,
256 PnaclRefCount> callback_factory_;
151 257
152 // URLs used to lookup downloaded resources. 258 // URLs used to lookup downloaded resources.
153 nacl::string resource_base_url_; 259 nacl::string resource_base_url_;
154 nacl::string llc_url_;
155 nacl::string ld_url_;
156 260
157 // Helper subprocesses loaded by the plugin (deleted by the plugin). 261 // Helper subprocesses loaded by the plugin (deleted by the plugin).
158 // We may want to do cleanup ourselves when we are in the 262 // A nacl sandbox running the llc nexe.
159 // business of compiling multiple bitcode objects / libraries, and
160 // if we truly cannot reuse existing loaded subprocesses.
161 NaClSubprocess* llc_subprocess_; 263 NaClSubprocess* llc_subprocess_;
264 // A nacl sandbox running the ld nexe.
162 NaClSubprocess* ld_subprocess_; 265 NaClSubprocess* ld_subprocess_;
266 // True if the translation thread and subprocesses should exit.
163 bool subprocesses_should_die_; 267 bool subprocesses_should_die_;
268 // Used to guard and publish subprocesses_should_die_.
164 struct NaClMutex subprocess_mu_; 269 struct NaClMutex subprocess_mu_;
165 270
166 // Nexe from the final native Link. 271 // Nexe from the final native Link.
167 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; 272 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_;
168 273
169 // Perhaps make this a single thread that invokes (S)RPCs followed by 274 // The helper thread used to do translations via SRPC.
170 // callbacks based on a Queue of requests. A generic mechanism would make
171 // it easier to add steps later (the mechanism could look like PostMessage?).
172 nacl::scoped_ptr<PnaclTranslationUnit> translation_unit_;
173 nacl::scoped_ptr<NaClThread> translate_thread_; 275 nacl::scoped_ptr<NaClThread> translate_thread_;
174 nacl::scoped_ptr<NaClThread> link_thread_; 276 // Translation creates local temporary files.
175 277 nacl::scoped_ptr<pp::FileSystem> file_system_;
176 // An auxiliary class that manages downloaded resources. 278 // An auxiliary class that manages downloaded resources (llc and ld nexes).
177 nacl::scoped_ptr<PnaclResources> resources_; 279 nacl::scoped_ptr<PnaclResources> resources_;
280
281 // The URL for the pexe file.
282 nacl::string pexe_url_;
283 // Borrowed reference which must outlive the thread.
284 nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper_;
285 // Object file, produced by the translator and consumed by the linker.
286 nacl::scoped_ptr<PnaclFileDescPair> obj_file_;
287 // Translated nexe file, produced by the linker and consumed by sel_ldr.
288 nacl::scoped_ptr<PnaclFileDescPair> nexe_file_;
289 // Callbacks to run when tasks or completed or an error has occurred.
290 pp::CompletionCallback translate_done_cb_;
291
292 // Used to report information when errors (PPAPI or otherwise) are reported.
293 ErrorInfo error_info_;
294
295 // Support for file lookups (obsolescent).
296 // The SRPC file lookup service for ld.
297 static void LookupInputFile(NaClSrpcRpc* rpc,
298 NaClSrpcArg** inputs,
299 NaClSrpcArg** outputs,
300 NaClSrpcClosure* done);
301 static NaClSrpcHandlerDesc lookup_methods[];
302
303 // Used by the SRPC file lookup service for ld.
304 // Looks up url and returns the read-only file descriptor for it.
305 // If url is the specially designated filename for the translated object
306 // file, it returns obj_file_.read_wrapper(). Otherwise the lookup causes
307 // the download of the requested resource via Plugin::StreamAsFile.
308 struct NaClDesc* LookupDesc(const nacl::string& url);
309
310 struct NaClMutex lookup_service_mu_;
311 struct NaClCondVar lookup_service_cv_;
312 bool lookup_is_complete_;
178 }; 313 };
179 314
180 //---------------------------------------------------------------------- 315 //----------------------------------------------------------------------
181 316
182 } // namespace plugin; 317 } // namespace plugin;
183 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ 318 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/plugin.cc ('k') | ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698