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

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

Issue 10377157: Refactor Pnacl coordinator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sehr comments Created 8 years, 7 months 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" 5 #include "native_client/src/trusted/plugin/pnacl_coordinator.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "native_client/src/include/portability_io.h" 10 #include "native_client/src/include/portability_io.h"
11 #include "native_client/src/shared/platform/nacl_check.h" 11 #include "native_client/src/shared/platform/nacl_check.h"
12 #include "native_client/src/shared/platform/nacl_sync_raii.h" 12 #include "native_client/src/trusted/plugin/local_temp_file.h"
13 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
14 #include "native_client/src/trusted/plugin/manifest.h" 13 #include "native_client/src/trusted/plugin/manifest.h"
15 #include "native_client/src/trusted/plugin/nacl_subprocess.h"
16 #include "native_client/src/trusted/plugin/nexe_arch.h"
17 #include "native_client/src/trusted/plugin/plugin.h" 14 #include "native_client/src/trusted/plugin/plugin.h"
18 #include "native_client/src/trusted/plugin/plugin_error.h" 15 #include "native_client/src/trusted/plugin/plugin_error.h"
16 #include "native_client/src/trusted/plugin/pnacl_translate_thread.h"
19 #include "native_client/src/trusted/plugin/service_runtime.h" 17 #include "native_client/src/trusted/plugin/service_runtime.h"
20 #include "native_client/src/trusted/plugin/srpc_params.h"
21 #include "native_client/src/trusted/plugin/utility.h"
22 #include "native_client/src/trusted/service_runtime/include/sys/stat.h" 18 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
23 19
24 #include "ppapi/c/pp_errors.h" 20 #include "ppapi/c/pp_errors.h"
25 #include "ppapi/c/ppb_file_io.h" 21 #include "ppapi/c/ppb_file_io.h"
26 #include "ppapi/cpp/file_io.h" 22 #include "ppapi/cpp/file_io.h"
27 23
28 namespace plugin {
29
30 class Plugin;
31
32 namespace { 24 namespace {
33
34 const char kLlcUrl[] = "llc";
35 const char kLdUrl[] = "ld";
36 const char kPnaclTempDir[] = "/.pnacl"; 25 const char kPnaclTempDir[] = "/.pnacl";
37
38 nacl::string ExtensionUrl() {
39 // TODO(sehr,jvoung): Find a better way to express the URL for the pnacl
40 // extension than a constant string here.
41 const nacl::string kPnaclExtensionOrigin =
42 "chrome-extension://gcodniebolpnpaiggndmcmmfpldlknih/";
43 return kPnaclExtensionOrigin + GetSandboxISA() + "/";
44 } 26 }
45 27
46 nacl::string Random32CharHexString(struct NaClDescRng* rng) { 28 namespace plugin {
47 struct NaClDesc* desc = reinterpret_cast<struct NaClDesc*>(rng);
48 const struct NaClDescVtbl* vtbl =
49 reinterpret_cast<const struct NaClDescVtbl*>(desc->base.vtbl);
50
51 nacl::string hex_string;
52 const int32_t kTempFileNameWords = 4;
53 for (int32_t i = 0; i < kTempFileNameWords; ++i) {
54 int32_t num;
55 CHECK(sizeof num == vtbl->Read(desc,
56 reinterpret_cast<char*>(&num),
57 sizeof num));
58 char frag[16];
59 SNPRINTF(frag, sizeof frag, "%08x", num);
60 hex_string += nacl::string(frag);
61 }
62 return hex_string;
63 }
64
65 // Some constants for PnaclFileDescPair::GetFD readability.
66 const bool kReadOnly = false;
67 const bool kWriteable = true;
68 } // namespace
69
70 //////////////////////////////////////////////////////////////////////
71 // Local temporary file access.
72 //////////////////////////////////////////////////////////////////////
73
74 uint32_t LocalTempFile::next_identifier = 0;
75
76 LocalTempFile::LocalTempFile(Plugin* plugin,
77 pp::FileSystem* file_system)
78 : plugin_(plugin),
79 file_system_(file_system) {
80 PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, "
81 "file_system=%p)\n",
82 static_cast<void*>(plugin), static_cast<void*>(file_system)));
83 Initialize();
84 }
85
86 LocalTempFile::LocalTempFile(Plugin* plugin,
87 pp::FileSystem* file_system,
88 const nacl::string &filename)
89 : plugin_(plugin),
90 file_system_(file_system),
91 filename_(nacl::string(kPnaclTempDir) + "/" + filename) {
92 PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, "
93 "file_system=%p, filename=%s)\n",
94 static_cast<void*>(plugin), static_cast<void*>(file_system),
95 filename.c_str()));
96 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
97 Initialize();
98 }
99
100 void LocalTempFile::Initialize() {
101 callback_factory_.Initialize(this);
102 rng_desc_ = (struct NaClDescRng *) malloc(sizeof *rng_desc_);
103 CHECK(rng_desc_ != NULL);
104 CHECK(NaClDescRngCtor(rng_desc_));
105 file_io_trusted_ = static_cast<const PPB_FileIOTrusted*>(
106 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE));
107 ++next_identifier;
108 SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_,
109 "%"NACL_PRIu32, next_identifier);
110 }
111
112 LocalTempFile::~LocalTempFile() {
113 PLUGIN_PRINTF(("LocalTempFile::~LocalTempFile\n"));
114 NaClDescUnref(reinterpret_cast<NaClDesc*>(rng_desc_));
115 }
116
117 void LocalTempFile::OpenWrite(const pp::CompletionCallback& cb) {
118 done_callback_ = cb;
119 // If we don't already have a filename, generate one.
120 if (filename_ == "") {
121 // Get a random temp file name.
122 filename_ =
123 nacl::string(kPnaclTempDir) + "/" + Random32CharHexString(rng_desc_);
124 // Remember the ref used to open for writing and reading.
125 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
126 }
127 PLUGIN_PRINTF(("LocalTempFile::OpenWrite: %s\n", filename_.c_str()));
128 // Open the writeable file.
129 write_io_.reset(new pp::FileIO(plugin_));
130 pp::CompletionCallback open_write_cb =
131 callback_factory_.NewCallback(&LocalTempFile::WriteFileDidOpen);
132 write_io_->Open(*file_ref_,
133 PP_FILEOPENFLAG_WRITE |
134 PP_FILEOPENFLAG_CREATE |
135 PP_FILEOPENFLAG_EXCLUSIVE,
136 open_write_cb);
137 }
138
139 int32_t LocalTempFile::GetFD(int32_t pp_error,
140 const pp::Resource& resource,
141 bool is_writable) {
142 PLUGIN_PRINTF(("LocalTempFile::GetFD (pp_error=%"NACL_PRId32
143 ", is_writable=%d)\n", pp_error, is_writable));
144 if (pp_error != PP_OK) {
145 PLUGIN_PRINTF(("LocalTempFile::GetFD pp_error != PP_OK\n"));
146 return -1;
147 }
148 int32_t file_desc =
149 file_io_trusted_->GetOSFileDescriptor(resource.pp_resource());
150 #if NACL_WINDOWS
151 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor.
152 int32_t open_flags = ((is_writable ? _O_RDWR : _O_RDONLY) | _O_BINARY);
153 int32_t posix_desc = _open_osfhandle(file_desc, open_flags);
154 if (posix_desc == -1) {
155 // Close the Windows HANDLE if it can't be converted.
156 CloseHandle(reinterpret_cast<HANDLE>(file_desc));
157 PLUGIN_PRINTF(("LocalTempFile::GetFD _open_osfhandle failed.\n"));
158 return NACL_NO_FILE_DESC;
159 }
160 file_desc = posix_desc;
161 #endif
162 int32_t file_desc_ok_to_close = DUP(file_desc);
163 if (file_desc_ok_to_close == NACL_NO_FILE_DESC) {
164 PLUGIN_PRINTF(("LocalTempFile::GetFD dup failed.\n"));
165 return -1;
166 }
167 return file_desc_ok_to_close;
168 }
169
170 void LocalTempFile::WriteFileDidOpen(int32_t pp_error) {
171 PLUGIN_PRINTF(("LocalTempFile::WriteFileDidOpen (pp_error=%"
172 NACL_PRId32")\n", pp_error));
173 if (pp_error == PP_ERROR_FILEEXISTS) {
174 // Filenames clashed, retry.
175 filename_ = "";
176 OpenWrite(done_callback_);
177 }
178 // Run the client's completion callback.
179 pp::Core* core = pp::Module::Get()->core();
180 if (pp_error != PP_OK) {
181 core->CallOnMainThread(0, done_callback_, pp_error);
182 return;
183 }
184 // Remember the object temporary file descriptor.
185 int32_t fd = GetFD(pp_error, *write_io_, kWriteable);
186 if (fd < 0) {
187 core->CallOnMainThread(0, done_callback_, pp_error);
188 return;
189 }
190 // The descriptor for a writeable file needs to have quota management.
191 write_wrapper_.reset(
192 plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_));
193 core->CallOnMainThread(0, done_callback_, PP_OK);
194 }
195
196 void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) {
197 PLUGIN_PRINTF(("LocalTempFile::OpenRead: %s\n", filename_.c_str()));
198 done_callback_ = cb;
199 // Open the read only file.
200 read_io_.reset(new pp::FileIO(plugin_));
201 pp::CompletionCallback open_read_cb =
202 callback_factory_.NewCallback(&LocalTempFile::ReadFileDidOpen);
203 read_io_->Open(*file_ref_, PP_FILEOPENFLAG_READ, open_read_cb);
204 }
205
206 void LocalTempFile::ReadFileDidOpen(int32_t pp_error) {
207 PLUGIN_PRINTF(("LocalTempFile::ReadFileDidOpen (pp_error=%"
208 NACL_PRId32")\n", pp_error));
209 // Run the client's completion callback.
210 pp::Core* core = pp::Module::Get()->core();
211 if (pp_error != PP_OK) {
212 core->CallOnMainThread(0, done_callback_, pp_error);
213 return;
214 }
215 // Remember the object temporary file descriptor.
216 int32_t fd = GetFD(pp_error, *read_io_, kReadOnly);
217 if (fd < 0) {
218 core->CallOnMainThread(0, done_callback_, PP_ERROR_FAILED);
219 return;
220 }
221 read_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY));
222 core->CallOnMainThread(0, done_callback_, PP_OK);
223 }
224
225 void LocalTempFile::Close(const pp::CompletionCallback& cb) {
226 PLUGIN_PRINTF(("LocalTempFile::Close: %s\n", filename_.c_str()));
227 // Close the open DescWrappers and FileIOs.
228 if (write_io_.get() != NULL) {
229 write_io_->Close();
230 }
231 write_wrapper_.reset(NULL);
232 write_io_.reset(NULL);
233 if (read_io_.get() != NULL) {
234 read_io_->Close();
235 }
236 read_wrapper_.reset(NULL);
237 read_io_.reset(NULL);
238 // Run the client's completion callback.
239 pp::Core* core = pp::Module::Get()->core();
240 core->CallOnMainThread(0, cb, PP_OK);
241 }
242
243 void LocalTempFile::Delete(const pp::CompletionCallback& cb) {
244 PLUGIN_PRINTF(("LocalTempFile::Delete: %s\n", filename_.c_str()));
245 file_ref_->Delete(cb);
246 }
247
248 void LocalTempFile::Rename(const nacl::string& new_name,
249 const pp::CompletionCallback& cb) {
250 // Rename the temporary file.
251 filename_ = nacl::string(kPnaclTempDir) + "/" + new_name;
252 PLUGIN_PRINTF(("LocalTempFile::Rename %s to %s\n",
253 file_ref_->GetName().AsString().c_str(),
254 filename_.c_str()));
255 // Remember the old ref until the rename is complete.
256 old_ref_.reset(file_ref_.release());
257 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str()));
258 old_ref_->Rename(*file_ref_, cb);
259 }
260
261 void LocalTempFile::FinishRename() {
262 // Now we can release the old ref.
263 old_ref_.reset(NULL);
264 }
265
266 29
267 ////////////////////////////////////////////////////////////////////// 30 //////////////////////////////////////////////////////////////////////
268 // Pnacl-specific manifest support. 31 // Pnacl-specific manifest support.
269 ////////////////////////////////////////////////////////////////////// 32 //////////////////////////////////////////////////////////////////////
270 class ExtensionManifest : public Manifest { 33 class ExtensionManifest : public Manifest {
271 public: 34 public:
272 explicit ExtensionManifest(const pp::URLUtil_Dev* url_util) 35 explicit ExtensionManifest(const pp::URLUtil_Dev* url_util)
273 : url_util_(url_util), 36 : url_util_(url_util),
274 manifest_base_url_(ExtensionUrl()) { } 37 manifest_base_url_(PnaclUrls::GetExtensionUrl()) { }
275 virtual ~ExtensionManifest() { } 38 virtual ~ExtensionManifest() { }
276 39
277 virtual bool GetProgramURL(nacl::string* full_url, 40 virtual bool GetProgramURL(nacl::string* full_url,
278 nacl::string* cache_identity, 41 nacl::string* cache_identity,
279 ErrorInfo* error_info, 42 ErrorInfo* error_info,
280 bool* pnacl_translate) const { 43 bool* pnacl_translate) const {
281 // Does not contain program urls. 44 // Does not contain program urls.
282 UNREFERENCED_PARAMETER(full_url); 45 UNREFERENCED_PARAMETER(full_url);
283 UNREFERENCED_PARAMETER(cache_identity); 46 UNREFERENCED_PARAMETER(cache_identity);
284 UNREFERENCED_PARAMETER(error_info); 47 UNREFERENCED_PARAMETER(error_info);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 const pp::CompletionCallback& translate_notify_callback) { 172 const pp::CompletionCallback& translate_notify_callback) {
410 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", 173 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n",
411 static_cast<void*>(plugin), pexe_url.c_str())); 174 static_cast<void*>(plugin), pexe_url.c_str()));
412 PnaclCoordinator* coordinator = 175 PnaclCoordinator* coordinator =
413 new PnaclCoordinator(plugin, pexe_url, 176 new PnaclCoordinator(plugin, pexe_url,
414 cache_identity, translate_notify_callback); 177 cache_identity, translate_notify_callback);
415 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p)\n", 178 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p)\n",
416 reinterpret_cast<const void*>(coordinator->manifest_.get()))); 179 reinterpret_cast<const void*>(coordinator->manifest_.get())));
417 // Load llc and ld. 180 // Load llc and ld.
418 std::vector<nacl::string> resource_urls; 181 std::vector<nacl::string> resource_urls;
419 resource_urls.push_back(kLlcUrl); 182 resource_urls.push_back(PnaclUrls::GetLlcUrl());
420 resource_urls.push_back(kLdUrl); 183 resource_urls.push_back(PnaclUrls::GetLdUrl());
421 pp::CompletionCallback resources_cb = 184 pp::CompletionCallback resources_cb =
422 coordinator->callback_factory_.NewCallback( 185 coordinator->callback_factory_.NewCallback(
423 &PnaclCoordinator::ResourcesDidLoad); 186 &PnaclCoordinator::ResourcesDidLoad);
424 coordinator->resources_.reset( 187 coordinator->resources_.reset(
425 new PnaclResources(plugin, 188 new PnaclResources(plugin,
426 coordinator, 189 coordinator,
427 coordinator->manifest_.get(), 190 coordinator->manifest_.get(),
428 resource_urls, 191 resource_urls,
429 resources_cb)); 192 resources_cb));
430 CHECK(coordinator->resources_ != NULL); 193 CHECK(coordinator->resources_ != NULL);
(...skipping 21 matching lines...) Expand all
452 return file_desc_ok_to_close; 215 return file_desc_ok_to_close;
453 } 216 }
454 217
455 PnaclCoordinator::PnaclCoordinator( 218 PnaclCoordinator::PnaclCoordinator(
456 Plugin* plugin, 219 Plugin* plugin,
457 const nacl::string& pexe_url, 220 const nacl::string& pexe_url,
458 const nacl::string& cache_identity, 221 const nacl::string& cache_identity,
459 const pp::CompletionCallback& translate_notify_callback) 222 const pp::CompletionCallback& translate_notify_callback)
460 : plugin_(plugin), 223 : plugin_(plugin),
461 translate_notify_callback_(translate_notify_callback), 224 translate_notify_callback_(translate_notify_callback),
462 subprocesses_should_die_(false),
463 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), 225 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)),
464 manifest_(new ExtensionManifest(plugin->url_util())), 226 manifest_(new ExtensionManifest(plugin->url_util())),
465 pexe_url_(pexe_url), 227 pexe_url_(pexe_url),
466 cache_identity_(cache_identity), 228 cache_identity_(cache_identity),
467 error_already_reported_(false) { 229 error_already_reported_(false) {
468 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", 230 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n",
469 static_cast<void*>(this), static_cast<void*>(plugin))); 231 static_cast<void*>(this), static_cast<void*>(plugin)));
470 callback_factory_.Initialize(this); 232 callback_factory_.Initialize(this);
471 NaClXMutexCtor(&subprocess_mu_);
472 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get())); 233 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get()));
473 } 234 }
474 235
475 PnaclCoordinator::~PnaclCoordinator() { 236 PnaclCoordinator::~PnaclCoordinator() {
476 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p)\n", 237 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p)\n",
477 static_cast<void*>(this))); 238 static_cast<void*>(this)));
478 // Stopping the translate thread will cause the translate thread to try to 239 // Stopping the translate thread will cause the translate thread to try to
479 // run translation_complete_callback_ on the main thread. This destructor is 240 // run translation_complete_callback_ on the main thread. This destructor is
480 // running from the main thread, and by the time it exits, callback_factory_ 241 // running from the main thread, and by the time it exits, callback_factory_
481 // will have been destroyed. This will result in the cancellation of 242 // will have been destroyed. This will result in the cancellation of
482 // translation_complete_callback_, so no notification will be delivered. 243 // translation_complete_callback_, so no notification will be delivered.
483 if (translate_thread_.get() != NULL) { 244 if (translate_thread_.get() != NULL) {
484 SetSubprocessesShouldDie(true); 245 translate_thread_->SetSubprocessesShouldDie(true);
485 } 246 }
486 NaClMutexDtor(&subprocess_mu_);
487 } 247 }
488 248
489 void PnaclCoordinator::ReportNonPpapiError(const nacl::string& message) { 249 void PnaclCoordinator::ReportNonPpapiError(const nacl::string& message) {
490 error_info_.SetReport(ERROR_UNKNOWN, 250 error_info_.SetReport(ERROR_UNKNOWN,
491 nacl::string("PnaclCoordinator: ") + message); 251 nacl::string("PnaclCoordinator: ") + message);
492 ReportPpapiError(PP_ERROR_FAILED); 252 ReportPpapiError(PP_ERROR_FAILED);
493 } 253 }
494 254
495 void PnaclCoordinator::ReportPpapiError(int32_t pp_error, 255 void PnaclCoordinator::ReportPpapiError(int32_t pp_error,
496 const nacl::string& message) { 256 const nacl::string& message) {
(...skipping 17 matching lines...) Expand all
514 callback_factory_.CancelAll(); 274 callback_factory_.CancelAll();
515 if (!error_already_reported_) { 275 if (!error_already_reported_) {
516 error_already_reported_ = true; 276 error_already_reported_ = true;
517 translate_notify_callback_.Run(pp_error); 277 translate_notify_callback_.Run(pp_error);
518 } else { 278 } else {
519 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpapiError an earlier error was " 279 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpapiError an earlier error was "
520 "already reported -- Skipping.\n")); 280 "already reported -- Skipping.\n"));
521 } 281 }
522 } 282 }
523 283
284 // Signal that Pnacl translation completed normally.
524 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { 285 void PnaclCoordinator::TranslateFinished(int32_t pp_error) {
525 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" 286 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%"
526 NACL_PRId32")\n", pp_error)); 287 NACL_PRId32")\n", pp_error));
527 // Save the translate error code, and inspect after cleaning up junk files. 288 // Save the translate error code, and inspect after cleaning up junk files.
528 // Note: If there was a surfaway and the file objects were actually 289 // Note: If there was a surfaway and the file objects were actually
529 // destroyed, then we are in trouble since the obj_file_, nexe_file_, 290 // destroyed, then we are in trouble since the obj_file_, nexe_file_,
530 // etc. may have been destroyed. 291 // etc. may have been destroyed.
531 // TODO(jvoung,sehr): Fix. 292 // TODO(jvoung,sehr): Fix.
532 translate_finish_error_ = pp_error; 293 translate_finish_error_ = pp_error;
533 294
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); 381 plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress);
621 translate_notify_callback_.Run(pp_error); 382 translate_notify_callback_.Run(pp_error);
622 } 383 }
623 384
624 void PnaclCoordinator::NexeFileWasDeleted(int32_t pp_error) { 385 void PnaclCoordinator::NexeFileWasDeleted(int32_t pp_error) {
625 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasDeleted (pp_error=%" 386 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasDeleted (pp_error=%"
626 NACL_PRId32")\n", pp_error)); 387 NACL_PRId32")\n", pp_error));
627 ReportPpapiError(translate_finish_error_); 388 ReportPpapiError(translate_finish_error_);
628 } 389 }
629 390
630 void PnaclCoordinator::TranslateFailed(const nacl::string& error_string) {
631 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFailed (error_string='%s')\n",
632 error_string.c_str()));
633 pp::Core* core = pp::Module::Get()->core();
634 error_info_.SetReport(ERROR_UNKNOWN,
635 nacl::string("PnaclCoordinator: ") + error_string);
636 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED);
637 }
638
639 void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { 391 void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) {
640 PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" 392 PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%"
641 NACL_PRId32")\n", pp_error)); 393 NACL_PRId32")\n", pp_error));
642 if (pp_error != PP_OK) { 394 if (pp_error != PP_OK) {
643 ReportPpapiError(pp_error, "resources failed to load."); 395 ReportPpapiError(pp_error, "resources failed to load.");
644 return; 396 return;
645 } 397 }
646 // Open the local temporary file system to create the temporary files 398 // Open the local temporary file system to create the temporary files
647 // for the object and nexe. 399 // for the object and nexe.
648 pp::CompletionCallback cb = 400 pp::CompletionCallback cb =
649 callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen); 401 callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen);
650 if (!file_system_->Open(0, cb)) { 402 if (!file_system_->Open(0, cb)) {
651 ReportNonPpapiError("failed to open file system."); 403 ReportNonPpapiError("failed to open file system.");
652 } 404 }
653 } 405 }
654 406
655 void PnaclCoordinator::FileSystemDidOpen(int32_t pp_error) { 407 void PnaclCoordinator::FileSystemDidOpen(int32_t pp_error) {
656 PLUGIN_PRINTF(("PnaclCoordinator::FileSystemDidOpen (pp_error=%" 408 PLUGIN_PRINTF(("PnaclCoordinator::FileSystemDidOpen (pp_error=%"
657 NACL_PRId32")\n", pp_error)); 409 NACL_PRId32")\n", pp_error));
658 if (pp_error != PP_OK) { 410 if (pp_error != PP_OK) {
659 ReportPpapiError(pp_error, "file system didn't open."); 411 ReportPpapiError(pp_error, "file system didn't open.");
660 return; 412 return;
661 } 413 }
662 dir_ref_.reset(new pp::FileRef(*file_system_, kPnaclTempDir)); 414 dir_ref_.reset(new pp::FileRef(*file_system_,
415 kPnaclTempDir));
663 dir_io_.reset(new pp::FileIO(plugin_)); 416 dir_io_.reset(new pp::FileIO(plugin_));
664 // Attempt to create the directory. 417 // Attempt to create the directory.
665 pp::CompletionCallback cb = 418 pp::CompletionCallback cb =
666 callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated); 419 callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated);
667 dir_ref_->MakeDirectory(cb); 420 dir_ref_->MakeDirectory(cb);
668 } 421 }
669 422
670 void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { 423 void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) {
671 PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasCreated (pp_error=%" 424 PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasCreated (pp_error=%"
672 NACL_PRId32")\n", pp_error)); 425 NACL_PRId32")\n", pp_error));
673 if (pp_error != PP_ERROR_FILEEXISTS && pp_error != PP_OK) { 426 if (pp_error != PP_ERROR_FILEEXISTS && pp_error != PP_OK) {
674 // Directory did not exist and could not be created. 427 // Directory did not exist and could not be created.
675 ReportPpapiError(pp_error, "directory creation/check failed."); 428 ReportPpapiError(pp_error, "directory creation/check failed.");
676 return; 429 return;
677 } 430 }
678 if (cache_identity_ != "") { 431 if (cache_identity_ != "") {
679 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), 432 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
433 nacl::string(kPnaclTempDir),
680 cache_identity_)); 434 cache_identity_));
681 pp::CompletionCallback cb = 435 pp::CompletionCallback cb =
682 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); 436 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen);
683 nexe_file_->OpenRead(cb); 437 nexe_file_->OpenRead(cb);
684 } else { 438 } else {
685 // For now, tolerate lack of cache identity... 439 // For now, tolerate lack of cache identity...
686 CachedFileDidOpen(PP_ERROR_FAILED); 440 CachedFileDidOpen(PP_ERROR_FAILED);
687 } 441 }
688 } 442 }
689 443
(...skipping 17 matching lines...) Expand all
707 NACL_PRId32")\n", pp_error)); 461 NACL_PRId32")\n", pp_error));
708 // We have to get the fd immediately after streaming, otherwise it 462 // We have to get the fd immediately after streaming, otherwise it
709 // seems like the temp file will get GC'ed. 463 // seems like the temp file will get GC'ed.
710 int32_t fd = GetLoadedFileDesc(pp_error, pexe_url_, "pexe"); 464 int32_t fd = GetLoadedFileDesc(pp_error, pexe_url_, "pexe");
711 if (fd < 0) { 465 if (fd < 0) {
712 // Error already reported by GetLoadedFileDesc(). 466 // Error already reported by GetLoadedFileDesc().
713 return; 467 return;
714 } 468 }
715 pexe_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); 469 pexe_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY));
716 470
717 obj_file_.reset(new LocalTempFile(plugin_, file_system_.get())); 471 obj_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
472 nacl::string(kPnaclTempDir)));
718 pp::CompletionCallback cb = 473 pp::CompletionCallback cb =
719 callback_factory_.NewCallback(&PnaclCoordinator::ObjectWriteDidOpen); 474 callback_factory_.NewCallback(&PnaclCoordinator::ObjectWriteDidOpen);
720 obj_file_->OpenWrite(cb); 475 obj_file_->OpenWrite(cb);
721 } 476 }
722 477
723 void PnaclCoordinator::ObjectWriteDidOpen(int32_t pp_error) { 478 void PnaclCoordinator::ObjectWriteDidOpen(int32_t pp_error) {
724 PLUGIN_PRINTF(("PnaclCoordinator::ObjectWriteDidOpen (pp_error=%" 479 PLUGIN_PRINTF(("PnaclCoordinator::ObjectWriteDidOpen (pp_error=%"
725 NACL_PRId32")\n", pp_error)); 480 NACL_PRId32")\n", pp_error));
726 if (pp_error != PP_OK) { 481 if (pp_error != PP_OK) {
727 ReportPpapiError(pp_error); 482 ReportPpapiError(pp_error);
728 return; 483 return;
729 } 484 }
730 pp::CompletionCallback cb = 485 pp::CompletionCallback cb =
731 callback_factory_.NewCallback(&PnaclCoordinator::ObjectReadDidOpen); 486 callback_factory_.NewCallback(&PnaclCoordinator::ObjectReadDidOpen);
732 obj_file_->OpenRead(cb); 487 obj_file_->OpenRead(cb);
733 } 488 }
734 489
735 void PnaclCoordinator::ObjectReadDidOpen(int32_t pp_error) { 490 void PnaclCoordinator::ObjectReadDidOpen(int32_t pp_error) {
736 PLUGIN_PRINTF(("PnaclCoordinator::ObjectReadDidOpen (pp_error=%" 491 PLUGIN_PRINTF(("PnaclCoordinator::ObjectReadDidOpen (pp_error=%"
737 NACL_PRId32")\n", pp_error)); 492 NACL_PRId32")\n", pp_error));
738 if (pp_error != PP_OK) { 493 if (pp_error != PP_OK) {
739 ReportPpapiError(pp_error); 494 ReportPpapiError(pp_error);
740 return; 495 return;
741 } 496 }
742 // Create the nexe file for connecting ld and sel_ldr. 497 // Create the nexe file for connecting ld and sel_ldr.
743 // Start translation when done with this last step of setup! 498 // Start translation when done with this last step of setup!
744 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get())); 499 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
500 nacl::string(kPnaclTempDir)));
745 pp::CompletionCallback cb = 501 pp::CompletionCallback cb =
746 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); 502 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate);
747 nexe_file_->OpenWrite(cb); 503 nexe_file_->OpenWrite(cb);
748 } 504 }
749 505
750 void PnaclCoordinator::RunTranslate(int32_t pp_error) { 506 void PnaclCoordinator::RunTranslate(int32_t pp_error) {
751 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" 507 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%"
752 NACL_PRId32")\n", pp_error)); 508 NACL_PRId32")\n", pp_error));
753 // Invoke llc followed by ld off the main thread. This allows use of 509 // Invoke llc followed by ld off the main thread. This allows use of
754 // blocking RPCs that would otherwise block the JavaScript main thread. 510 // blocking RPCs that would otherwise block the JavaScript main thread.
755 report_translate_finished_ = 511 pp::CompletionCallback report_translate_finished =
756 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); 512 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished);
757 translate_thread_.reset(new NaClThread); 513 translate_thread_.reset(new PnaclTranslateThread());
758 if (translate_thread_ == NULL) { 514 if (translate_thread_ == NULL) {
759 ReportNonPpapiError("could not allocate thread struct."); 515 ReportNonPpapiError("could not allocate translation thread.");
760 return; 516 return;
761 } 517 }
762 const int32_t kArbitraryStackSize = 128 * 1024; 518 translate_thread_->RunTranslate(report_translate_finished,
763 if (!NaClThreadCreateJoinable(translate_thread_.get(), 519 manifest_.get(),
764 DoTranslateThread, 520 ld_manifest_.get(),
765 this, 521 obj_file_.get(),
766 kArbitraryStackSize)) { 522 nexe_file_.get(),
767 ReportNonPpapiError("could not create thread."); 523 pexe_wrapper_.get(),
768 } 524 &error_info_,
769 } 525 resources_.get(),
770 526 plugin_);
771 NaClSubprocess* PnaclCoordinator::StartSubprocess(
772 const nacl::string& url_for_nexe,
773 const Manifest* manifest) {
774 PLUGIN_PRINTF(("PnaclCoordinator::StartSubprocess (url_for_nexe=%s)\n",
775 url_for_nexe.c_str()));
776 nacl::DescWrapper* wrapper = resources_->WrapperForUrl(url_for_nexe);
777 nacl::scoped_ptr<NaClSubprocess> subprocess(
778 plugin_->LoadHelperNaClModule(wrapper, manifest, &error_info_));
779 if (subprocess.get() == NULL) {
780 PLUGIN_PRINTF((
781 "PnaclCoordinator::StartSubprocess: subprocess creation failed\n"));
782 return NULL;
783 }
784 return subprocess.release();
785 }
786
787 // TODO(sehr): the thread body should be in a class by itself with a delegate
788 // class for interfacing with the rest of the coordinator.
789 void WINAPI PnaclCoordinator::DoTranslateThread(void* arg) {
790 PnaclCoordinator* coordinator = reinterpret_cast<PnaclCoordinator*>(arg);
791
792 nacl::scoped_ptr<NaClSubprocess> llc_subprocess(
793 coordinator->StartSubprocess(kLlcUrl, coordinator->manifest_.get()));
794 if (llc_subprocess == NULL) {
795 coordinator->TranslateFailed("Compile process could not be created.");
796 return;
797 }
798 // Run LLC.
799 SrpcParams params;
800 nacl::DescWrapper* llc_out_file = coordinator->obj_file_->write_wrapper();
801 PluginReverseInterface* llc_reverse =
802 llc_subprocess->service_runtime()->rev_interface();
803 llc_reverse->AddQuotaManagedFile(coordinator->obj_file_->identifier(),
804 coordinator->obj_file_->write_file_io());
805 if (!llc_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine",
806 "hh",
807 &params,
808 coordinator->pexe_wrapper_->desc(),
809 llc_out_file->desc())) {
810 coordinator->TranslateFailed("compile failed.");
811 return;
812 }
813 // LLC returns values that are used to determine how linking is done.
814 int is_shared_library = (params.outs()[0]->u.ival != 0);
815 nacl::string soname = params.outs()[1]->arrays.str;
816 nacl::string lib_dependencies = params.outs()[2]->arrays.str;
817 PLUGIN_PRINTF(("PnaclCoordinator: compile (coordinator=%p) succeeded"
818 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n",
819 arg, is_shared_library, soname.c_str(),
820 lib_dependencies.c_str()));
821 // Shut down the llc subprocess.
822 llc_subprocess.reset(NULL);
823 if (coordinator->SubprocessesShouldDie()) {
824 coordinator->TranslateFailed("stopped by coordinator.");
825 return;
826 }
827 nacl::scoped_ptr<NaClSubprocess> ld_subprocess(
828 coordinator->StartSubprocess(kLdUrl, coordinator->ld_manifest_.get()));
829 if (ld_subprocess == NULL) {
830 coordinator->TranslateFailed("Link process could not be created.");
831 return;
832 }
833 // Run LD.
834 nacl::DescWrapper* ld_in_file = coordinator->obj_file_->read_wrapper();
835 nacl::DescWrapper* ld_out_file = coordinator->nexe_file_->write_wrapper();
836 PluginReverseInterface* ld_reverse =
837 ld_subprocess->service_runtime()->rev_interface();
838 ld_reverse->AddQuotaManagedFile(coordinator->nexe_file_->identifier(),
839 coordinator->nexe_file_->write_file_io());
840 if (!ld_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine",
841 "hhiCC",
842 &params,
843 ld_in_file->desc(),
844 ld_out_file->desc(),
845 is_shared_library,
846 soname.c_str(),
847 lib_dependencies.c_str())) {
848 coordinator->TranslateFailed("link failed.");
849 return;
850 }
851 PLUGIN_PRINTF(("PnaclCoordinator: link (coordinator=%p) succeeded\n", arg));
852 // Shut down the ld subprocess.
853 ld_subprocess.reset(NULL);
854 if (coordinator->SubprocessesShouldDie()) {
855 coordinator->TranslateFailed("stopped by coordinator.");
856 return;
857 }
858 pp::Core* core = pp::Module::Get()->core();
859 core->CallOnMainThread(0, coordinator->report_translate_finished_, PP_OK);
860 }
861
862 bool PnaclCoordinator::SubprocessesShouldDie() {
863 nacl::MutexLocker ml(&subprocess_mu_);
864 return subprocesses_should_die_;
865 }
866
867 void PnaclCoordinator::SetSubprocessesShouldDie(bool subprocesses_should_die) {
868 nacl::MutexLocker ml(&subprocess_mu_);
869 subprocesses_should_die_ = subprocesses_should_die;
870 } 527 }
871 528
872 } // namespace plugin 529 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h ('k') | ppapi/native_client/src/trusted/plugin/pnacl_resources.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698