OLD | NEW |
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" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_, | 108 SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_, |
109 "%"NACL_PRIu32, next_identifier); | 109 "%"NACL_PRIu32, next_identifier); |
110 } | 110 } |
111 | 111 |
112 LocalTempFile::~LocalTempFile() { | 112 LocalTempFile::~LocalTempFile() { |
113 PLUGIN_PRINTF(("LocalTempFile::~LocalTempFile\n")); | 113 PLUGIN_PRINTF(("LocalTempFile::~LocalTempFile\n")); |
114 NaClDescUnref(reinterpret_cast<NaClDesc*>(rng_desc_)); | 114 NaClDescUnref(reinterpret_cast<NaClDesc*>(rng_desc_)); |
115 } | 115 } |
116 | 116 |
117 void LocalTempFile::OpenWrite(const pp::CompletionCallback& cb) { | 117 void LocalTempFile::OpenWrite(const pp::CompletionCallback& cb) { |
118 PLUGIN_PRINTF(("LocalTempFile::OpenWrite\n")); | |
119 done_callback_ = cb; | 118 done_callback_ = cb; |
120 // If we don't already have a filename, generate one. | 119 // If we don't already have a filename, generate one. |
121 if (filename_ == "") { | 120 if (filename_ == "") { |
122 // Get a random temp file name. | 121 // Get a random temp file name. |
123 filename_ = | 122 filename_ = |
124 nacl::string(kPnaclTempDir) + "/" + Random32CharHexString(rng_desc_); | 123 nacl::string(kPnaclTempDir) + "/" + Random32CharHexString(rng_desc_); |
125 // Remember the ref used to open for writing and reading. | 124 // Remember the ref used to open for writing and reading. |
126 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); | 125 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); |
127 } | 126 } |
| 127 PLUGIN_PRINTF(("LocalTempFile::OpenWrite: %s\n", filename_.c_str())); |
128 // Open the writeable file. | 128 // Open the writeable file. |
129 write_io_.reset(new pp::FileIO(plugin_)); | 129 write_io_.reset(new pp::FileIO(plugin_)); |
130 pp::CompletionCallback open_write_cb = | 130 pp::CompletionCallback open_write_cb = |
131 callback_factory_.NewCallback(&LocalTempFile::WriteFileDidOpen); | 131 callback_factory_.NewCallback(&LocalTempFile::WriteFileDidOpen); |
132 write_io_->Open(*file_ref_, | 132 write_io_->Open(*file_ref_, |
133 PP_FILEOPENFLAG_WRITE | | 133 PP_FILEOPENFLAG_WRITE | |
134 PP_FILEOPENFLAG_CREATE | | 134 PP_FILEOPENFLAG_CREATE | |
135 PP_FILEOPENFLAG_EXCLUSIVE, | 135 PP_FILEOPENFLAG_EXCLUSIVE, |
136 open_write_cb); | 136 open_write_cb); |
137 } | 137 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 core->CallOnMainThread(0, done_callback_, pp_error); | 187 core->CallOnMainThread(0, done_callback_, pp_error); |
188 return; | 188 return; |
189 } | 189 } |
190 // The descriptor for a writeable file needs to have quota management. | 190 // The descriptor for a writeable file needs to have quota management. |
191 write_wrapper_.reset( | 191 write_wrapper_.reset( |
192 plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_)); | 192 plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_)); |
193 core->CallOnMainThread(0, done_callback_, PP_OK); | 193 core->CallOnMainThread(0, done_callback_, PP_OK); |
194 } | 194 } |
195 | 195 |
196 void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) { | 196 void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) { |
197 PLUGIN_PRINTF(("LocalTempFile::OpenRead\n")); | 197 PLUGIN_PRINTF(("LocalTempFile::OpenRead: %s\n", filename_.c_str())); |
198 done_callback_ = cb; | 198 done_callback_ = cb; |
199 // Open the read only file. | 199 // Open the read only file. |
200 read_io_.reset(new pp::FileIO(plugin_)); | 200 read_io_.reset(new pp::FileIO(plugin_)); |
201 pp::CompletionCallback open_read_cb = | 201 pp::CompletionCallback open_read_cb = |
202 callback_factory_.NewCallback(&LocalTempFile::ReadFileDidOpen); | 202 callback_factory_.NewCallback(&LocalTempFile::ReadFileDidOpen); |
203 read_io_->Open(*file_ref_, PP_FILEOPENFLAG_READ, open_read_cb); | 203 read_io_->Open(*file_ref_, PP_FILEOPENFLAG_READ, open_read_cb); |
204 } | 204 } |
205 | 205 |
206 void LocalTempFile::ReadFileDidOpen(int32_t pp_error) { | 206 void LocalTempFile::ReadFileDidOpen(int32_t pp_error) { |
207 PLUGIN_PRINTF(("LocalTempFile::ReadFileDidOpen (pp_error=%" | 207 PLUGIN_PRINTF(("LocalTempFile::ReadFileDidOpen (pp_error=%" |
208 NACL_PRId32")\n", pp_error)); | 208 NACL_PRId32")\n", pp_error)); |
209 // Run the client's completion callback. | 209 // Run the client's completion callback. |
210 pp::Core* core = pp::Module::Get()->core(); | 210 pp::Core* core = pp::Module::Get()->core(); |
211 if (pp_error != PP_OK) { | 211 if (pp_error != PP_OK) { |
212 core->CallOnMainThread(0, done_callback_, pp_error); | 212 core->CallOnMainThread(0, done_callback_, pp_error); |
213 return; | 213 return; |
214 } | 214 } |
215 // Remember the object temporary file descriptor. | 215 // Remember the object temporary file descriptor. |
216 int32_t fd = GetFD(pp_error, *read_io_, kReadOnly); | 216 int32_t fd = GetFD(pp_error, *read_io_, kReadOnly); |
217 if (fd < 0) { | 217 if (fd < 0) { |
218 core->CallOnMainThread(0, done_callback_, PP_ERROR_FAILED); | 218 core->CallOnMainThread(0, done_callback_, PP_ERROR_FAILED); |
219 return; | 219 return; |
220 } | 220 } |
221 read_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); | 221 read_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); |
222 core->CallOnMainThread(0, done_callback_, PP_OK); | 222 core->CallOnMainThread(0, done_callback_, PP_OK); |
223 } | 223 } |
224 | 224 |
225 void LocalTempFile::Close(const pp::CompletionCallback& cb) { | 225 void LocalTempFile::Close(const pp::CompletionCallback& cb) { |
226 PLUGIN_PRINTF(("LocalTempFile::Close\n")); | 226 PLUGIN_PRINTF(("LocalTempFile::Close: %s\n", filename_.c_str())); |
227 // Close the open DescWrappers and FileIOs. | 227 // Close the open DescWrappers and FileIOs. |
228 if (write_io_.get() != NULL) { | 228 if (write_io_.get() != NULL) { |
229 write_io_->Close(); | 229 write_io_->Close(); |
230 } | 230 } |
231 write_wrapper_.reset(NULL); | 231 write_wrapper_.reset(NULL); |
232 write_io_.reset(NULL); | 232 write_io_.reset(NULL); |
233 if (read_io_.get() != NULL) { | 233 if (read_io_.get() != NULL) { |
234 read_io_->Close(); | 234 read_io_->Close(); |
235 } | 235 } |
236 read_wrapper_.reset(NULL); | 236 read_wrapper_.reset(NULL); |
237 read_io_.reset(NULL); | 237 read_io_.reset(NULL); |
238 // Run the client's completion callback. | 238 // Run the client's completion callback. |
239 pp::Core* core = pp::Module::Get()->core(); | 239 pp::Core* core = pp::Module::Get()->core(); |
240 core->CallOnMainThread(0, cb, PP_OK); | 240 core->CallOnMainThread(0, cb, PP_OK); |
241 } | 241 } |
242 | 242 |
243 void LocalTempFile::Delete(const pp::CompletionCallback& cb) { | 243 void LocalTempFile::Delete(const pp::CompletionCallback& cb) { |
244 PLUGIN_PRINTF(("LocalTempFile::Delete\n")); | 244 PLUGIN_PRINTF(("LocalTempFile::Delete: %s\n", filename_.c_str())); |
245 file_ref_->Delete(cb); | 245 file_ref_->Delete(cb); |
246 } | 246 } |
247 | 247 |
248 void LocalTempFile::Rename(const nacl::string& new_name, | 248 void LocalTempFile::Rename(const nacl::string& new_name, |
249 const pp::CompletionCallback& cb) { | 249 const pp::CompletionCallback& cb) { |
250 // Rename the temporary file. | 250 // Rename the temporary file. |
251 filename_ = nacl::string(kPnaclTempDir) + "/" + new_name; | 251 filename_ = nacl::string(kPnaclTempDir) + "/" + new_name; |
252 PLUGIN_PRINTF(("LocalTempFile::Rename to %s\n", filename_.c_str())); | 252 PLUGIN_PRINTF(("LocalTempFile::Rename %s to %s\n", |
| 253 file_ref_->GetName().AsString().c_str(), |
| 254 filename_.c_str())); |
253 // Remember the old ref until the rename is complete. | 255 // Remember the old ref until the rename is complete. |
254 old_ref_.reset(file_ref_.release()); | 256 old_ref_.reset(file_ref_.release()); |
255 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); | 257 file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); |
256 old_ref_->Rename(*file_ref_, cb); | 258 old_ref_->Rename(*file_ref_, cb); |
257 } | 259 } |
258 | 260 |
259 void LocalTempFile::FinishRename() { | 261 void LocalTempFile::FinishRename() { |
260 // Now we can release the old ref. | 262 // Now we can release the old ref. |
261 old_ref_.reset(NULL); | 263 old_ref_.reset(NULL); |
262 } | 264 } |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // ResourcesDidLoad will be invoked when all resources have been received. | 432 // ResourcesDidLoad will be invoked when all resources have been received. |
431 return coordinator; | 433 return coordinator; |
432 } | 434 } |
433 | 435 |
434 int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, | 436 int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, |
435 const nacl::string& url, | 437 const nacl::string& url, |
436 const nacl::string& component) { | 438 const nacl::string& component) { |
437 PLUGIN_PRINTF(("PnaclCoordinator::GetLoadedFileDesc (pp_error=%" | 439 PLUGIN_PRINTF(("PnaclCoordinator::GetLoadedFileDesc (pp_error=%" |
438 NACL_PRId32", url=%s, component=%s)\n", pp_error, | 440 NACL_PRId32", url=%s, component=%s)\n", pp_error, |
439 url.c_str(), component.c_str())); | 441 url.c_str(), component.c_str())); |
440 PLUGIN_PRINTF(("PnaclCoordinator::GetLoadedFileDesc (pp_error=%d\n")); | |
441 ErrorInfo error_info; | 442 ErrorInfo error_info; |
442 int32_t file_desc = plugin_->GetPOSIXFileDesc(url); | 443 int32_t file_desc_ok_to_close = plugin_->GetPOSIXFileDesc(url); |
443 if (pp_error != PP_OK || file_desc == NACL_NO_FILE_DESC) { | 444 if (pp_error != PP_OK || file_desc_ok_to_close == NACL_NO_FILE_DESC) { |
444 if (pp_error == PP_ERROR_ABORTED) { | 445 if (pp_error == PP_ERROR_ABORTED) { |
445 plugin_->ReportLoadAbort(); | 446 plugin_->ReportLoadAbort(); |
446 } else { | 447 } else { |
447 ReportPpapiError(pp_error, component + " load failed."); | 448 ReportPpapiError(pp_error, component + " load failed."); |
448 } | 449 } |
449 return -1; | 450 return NACL_NO_FILE_DESC; |
450 } | |
451 int32_t file_desc_ok_to_close = DUP(file_desc); | |
452 if (file_desc_ok_to_close == NACL_NO_FILE_DESC) { | |
453 ReportPpapiError(PP_ERROR_FAILED, component + " could not dup fd."); | |
454 return -1; | |
455 } | 451 } |
456 return file_desc_ok_to_close; | 452 return file_desc_ok_to_close; |
457 } | 453 } |
458 | 454 |
459 PnaclCoordinator::PnaclCoordinator( | 455 PnaclCoordinator::PnaclCoordinator( |
460 Plugin* plugin, | 456 Plugin* plugin, |
461 const nacl::string& pexe_url, | 457 const nacl::string& pexe_url, |
462 const nacl::string& cache_identity, | 458 const nacl::string& cache_identity, |
463 const pp::CompletionCallback& translate_notify_callback) | 459 const pp::CompletionCallback& translate_notify_callback) |
464 : plugin_(plugin), | 460 : plugin_(plugin), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 | 494 |
499 void PnaclCoordinator::ReportPpapiError(int32_t pp_error, | 495 void PnaclCoordinator::ReportPpapiError(int32_t pp_error, |
500 const nacl::string& message) { | 496 const nacl::string& message) { |
501 error_info_.SetReport(ERROR_UNKNOWN, | 497 error_info_.SetReport(ERROR_UNKNOWN, |
502 nacl::string("PnaclCoordinator: ") + message); | 498 nacl::string("PnaclCoordinator: ") + message); |
503 ReportPpapiError(pp_error); | 499 ReportPpapiError(pp_error); |
504 } | 500 } |
505 | 501 |
506 void PnaclCoordinator::ReportPpapiError(int32_t pp_error) { | 502 void PnaclCoordinator::ReportPpapiError(int32_t pp_error) { |
507 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpappiError (pp_error=%" | 503 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpappiError (pp_error=%" |
508 NACL_PRId32", error_code=%d, message=%s)\n", | 504 NACL_PRId32", error_code=%d, message='%s')\n", |
509 pp_error, error_info_.error_code(), | 505 pp_error, error_info_.error_code(), |
510 error_info_.message().c_str())); | 506 error_info_.message().c_str())); |
511 plugin_->ReportLoadError(error_info_); | 507 plugin_->ReportLoadError(error_info_); |
512 // Free all the intermediate callbacks we ever created. | 508 // Free all the intermediate callbacks we ever created. |
513 // Note: this doesn't *cancel* the callbacks from the factories attached | 509 // Note: this doesn't *cancel* the callbacks from the factories attached |
514 // to the various helper classes (e.g., pnacl_resources). Thus, those | 510 // to the various helper classes (e.g., pnacl_resources). Thus, those |
515 // callbacks may still run asynchronously. We let those run but ignore | 511 // callbacks may still run asynchronously. We let those run but ignore |
516 // any other errors they may generate so that they do not end up running | 512 // any other errors they may generate so that they do not end up running |
517 // translate_notify_callback_, which has already been freed. | 513 // translate_notify_callback_, which has already been freed. |
518 callback_factory_.CancelAll(); | 514 callback_factory_.CancelAll(); |
519 if (!error_already_reported_) { | 515 if (!error_already_reported_) { |
520 error_already_reported_ = true; | 516 error_already_reported_ = true; |
521 translate_notify_callback_.Run(pp_error); | 517 translate_notify_callback_.Run(pp_error); |
522 } else { | 518 } else { |
523 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpapiError an earlier error was " | 519 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpapiError an earlier error was " |
524 "already reported -- Skipping.\n")); | 520 "already reported -- Skipping.\n")); |
525 } | 521 } |
526 } | 522 } |
527 | 523 |
528 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { | 524 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { |
529 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" | 525 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" |
530 NACL_PRId32")\n", pp_error)); | 526 NACL_PRId32")\n", pp_error)); |
531 if (pp_error != PP_OK) { | 527 // Save the translate error code, and inspect after cleaning up junk files. |
532 ReportPpapiError(pp_error); | 528 // Note: If there was a surfaway and the file objects were actually |
533 // TODO(sehr): Delete the object and nexe temporary files. | 529 // destroyed, then we are in trouble since the obj_file_, nexe_file_, |
534 return; | 530 // etc. may have been destroyed. |
535 } | 531 // TODO(jvoung,sehr): Fix. |
536 // Close the object temporary file. | 532 translate_finish_error_ = pp_error; |
| 533 |
| 534 // Close the object temporary file (regardless of error code). |
537 pp::CompletionCallback cb = | 535 pp::CompletionCallback cb = |
538 callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileWasClosed); | 536 callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileWasClosed); |
539 obj_file_->Close(cb); | 537 obj_file_->Close(cb); |
540 } | 538 } |
541 | 539 |
542 void PnaclCoordinator::ObjectFileWasClosed(int32_t pp_error) { | 540 void PnaclCoordinator::ObjectFileWasClosed(int32_t pp_error) { |
543 PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileWasClosed (pp_error=%" | 541 PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileWasClosed (pp_error=%" |
544 NACL_PRId32")\n", pp_error)); | 542 NACL_PRId32")\n", pp_error)); |
545 if (pp_error != PP_OK) { | 543 if (pp_error != PP_OK) { |
546 ReportPpapiError(pp_error); | 544 ReportPpapiError(pp_error); |
(...skipping 18 matching lines...) Expand all Loading... |
565 nexe_file_->Close(cb); | 563 nexe_file_->Close(cb); |
566 } | 564 } |
567 | 565 |
568 void PnaclCoordinator::NexeFileWasClosed(int32_t pp_error) { | 566 void PnaclCoordinator::NexeFileWasClosed(int32_t pp_error) { |
569 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasClosed (pp_error=%" | 567 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasClosed (pp_error=%" |
570 NACL_PRId32")\n", pp_error)); | 568 NACL_PRId32")\n", pp_error)); |
571 if (pp_error != PP_OK) { | 569 if (pp_error != PP_OK) { |
572 ReportPpapiError(pp_error); | 570 ReportPpapiError(pp_error); |
573 return; | 571 return; |
574 } | 572 } |
| 573 // Now that cleanup of the obj file is done, check the old TranslateFinished |
| 574 // error code to see if we should proceed normally or not. |
| 575 if (translate_finish_error_ != PP_OK) { |
| 576 pp::CompletionCallback cb = |
| 577 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasDeleted); |
| 578 nexe_file_->Delete(cb); |
| 579 return; |
| 580 } |
| 581 |
575 // Rename the nexe file to the cache id. | 582 // Rename the nexe file to the cache id. |
576 if (cache_identity_ != "") { | 583 if (cache_identity_ != "") { |
577 pp::CompletionCallback cb = | 584 pp::CompletionCallback cb = |
578 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); | 585 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); |
579 nexe_file_->Rename(cache_identity_, cb); | 586 nexe_file_->Rename(cache_identity_, cb); |
580 } else { | 587 } else { |
581 // For now tolerate bitcode that is missing a cache identity. | 588 // For now tolerate bitcode that is missing a cache identity. |
582 PLUGIN_PRINTF(("PnaclCoordinator -- WARNING: missing cache identity," | 589 PLUGIN_PRINTF(("PnaclCoordinator -- WARNING: missing cache identity," |
583 " not caching.\n")); | 590 " not caching.\n")); |
584 NexeFileWasRenamed(PP_OK); | 591 NexeFileWasRenamed(PP_OK); |
(...skipping 22 matching lines...) Expand all Loading... |
607 if (pp_error != PP_OK) { | 614 if (pp_error != PP_OK) { |
608 ReportPpapiError(pp_error, "Failed to open translated nexe."); | 615 ReportPpapiError(pp_error, "Failed to open translated nexe."); |
609 return; | 616 return; |
610 } | 617 } |
611 // Transfer ownership of the nexe wrapper to the coordinator. | 618 // Transfer ownership of the nexe wrapper to the coordinator. |
612 translated_fd_.reset(nexe_file_->release_read_wrapper()); | 619 translated_fd_.reset(nexe_file_->release_read_wrapper()); |
613 plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); | 620 plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); |
614 translate_notify_callback_.Run(pp_error); | 621 translate_notify_callback_.Run(pp_error); |
615 } | 622 } |
616 | 623 |
| 624 void PnaclCoordinator::NexeFileWasDeleted(int32_t pp_error) { |
| 625 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasDeleted (pp_error=%" |
| 626 NACL_PRId32")\n", pp_error)); |
| 627 ReportPpapiError(translate_finish_error_); |
| 628 } |
| 629 |
617 void PnaclCoordinator::TranslateFailed(const nacl::string& error_string) { | 630 void PnaclCoordinator::TranslateFailed(const nacl::string& error_string) { |
618 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFailed (error_string=%" | 631 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFailed (error_string='%s')\n", |
619 NACL_PRId32")\n", error_string.c_str())); | 632 error_string.c_str())); |
620 pp::Core* core = pp::Module::Get()->core(); | 633 pp::Core* core = pp::Module::Get()->core(); |
621 error_info_.SetReport(ERROR_UNKNOWN, | 634 error_info_.SetReport(ERROR_UNKNOWN, |
622 nacl::string("PnaclCoordinator: ") + error_string); | 635 nacl::string("PnaclCoordinator: ") + error_string); |
623 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); | 636 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); |
624 } | 637 } |
625 | 638 |
626 void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { | 639 void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { |
627 PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" | 640 PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" |
628 NACL_PRId32")\n", pp_error)); | 641 NACL_PRId32")\n", pp_error)); |
629 if (pp_error != PP_OK) { | 642 if (pp_error != PP_OK) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 pp::CompletionCallback cb = | 681 pp::CompletionCallback cb = |
669 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); | 682 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); |
670 nexe_file_->OpenRead(cb); | 683 nexe_file_->OpenRead(cb); |
671 } else { | 684 } else { |
672 // For now, tolerate lack of cache identity... | 685 // For now, tolerate lack of cache identity... |
673 CachedFileDidOpen(PP_ERROR_FAILED); | 686 CachedFileDidOpen(PP_ERROR_FAILED); |
674 } | 687 } |
675 } | 688 } |
676 | 689 |
677 void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { | 690 void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { |
678 | 691 PLUGIN_PRINTF(("PnaclCoordinator::CachedFileDidOpen (pp_error=%" |
| 692 NACL_PRId32")\n", pp_error)); |
679 if (pp_error == PP_OK) { | 693 if (pp_error == PP_OK) { |
680 NexeReadDidOpen(PP_OK); | 694 NexeReadDidOpen(PP_OK); |
681 return; | 695 return; |
682 } | 696 } |
| 697 // Otherwise, load the pexe and set up temp files for translation. |
| 698 pp::CompletionCallback cb = |
| 699 callback_factory_.NewCallback(&PnaclCoordinator::BitcodeFileDidOpen); |
| 700 if (!plugin_->StreamAsFile(pexe_url_, cb.pp_completion_callback())) { |
| 701 ReportNonPpapiError(nacl::string("failed to download ") + pexe_url_ + "."); |
| 702 } |
| 703 } |
| 704 |
| 705 void PnaclCoordinator::BitcodeFileDidOpen(int32_t pp_error) { |
| 706 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeFileDidOpen (pp_error=%" |
| 707 NACL_PRId32")\n", pp_error)); |
| 708 // We have to get the fd immediately after streaming, otherwise it |
| 709 // seems like the temp file will get GC'ed. |
| 710 int32_t fd = GetLoadedFileDesc(pp_error, pexe_url_, "pexe"); |
| 711 if (fd < 0) { |
| 712 // Error already reported by GetLoadedFileDesc(). |
| 713 return; |
| 714 } |
| 715 pexe_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); |
683 | 716 |
684 obj_file_.reset(new LocalTempFile(plugin_, file_system_.get())); | 717 obj_file_.reset(new LocalTempFile(plugin_, file_system_.get())); |
685 pp::CompletionCallback cb = | 718 pp::CompletionCallback cb = |
686 callback_factory_.NewCallback(&PnaclCoordinator::ObjectWriteDidOpen); | 719 callback_factory_.NewCallback(&PnaclCoordinator::ObjectWriteDidOpen); |
687 obj_file_->OpenWrite(cb); | 720 obj_file_->OpenWrite(cb); |
688 } | 721 } |
689 | 722 |
690 void PnaclCoordinator::ObjectWriteDidOpen(int32_t pp_error) { | 723 void PnaclCoordinator::ObjectWriteDidOpen(int32_t pp_error) { |
691 PLUGIN_PRINTF(("PnaclCoordinator::ObjectWriteDidOpen (pp_error=%" | 724 PLUGIN_PRINTF(("PnaclCoordinator::ObjectWriteDidOpen (pp_error=%" |
692 NACL_PRId32")\n", pp_error)); | 725 NACL_PRId32")\n", pp_error)); |
693 if (pp_error != PP_OK) { | 726 if (pp_error != PP_OK) { |
694 ReportPpapiError(pp_error); | 727 ReportPpapiError(pp_error); |
695 return; | 728 return; |
696 } | 729 } |
697 pp::CompletionCallback cb = | 730 pp::CompletionCallback cb = |
698 callback_factory_.NewCallback(&PnaclCoordinator::ObjectReadDidOpen); | 731 callback_factory_.NewCallback(&PnaclCoordinator::ObjectReadDidOpen); |
699 obj_file_->OpenRead(cb); | 732 obj_file_->OpenRead(cb); |
700 } | 733 } |
701 | 734 |
702 void PnaclCoordinator::ObjectReadDidOpen(int32_t pp_error) { | 735 void PnaclCoordinator::ObjectReadDidOpen(int32_t pp_error) { |
703 PLUGIN_PRINTF(("PnaclCoordinator::ObjectReadDidOpen (pp_error=%" | 736 PLUGIN_PRINTF(("PnaclCoordinator::ObjectReadDidOpen (pp_error=%" |
704 NACL_PRId32")\n", pp_error)); | 737 NACL_PRId32")\n", pp_error)); |
705 if (pp_error != PP_OK) { | 738 if (pp_error != PP_OK) { |
706 ReportPpapiError(pp_error); | 739 ReportPpapiError(pp_error); |
707 return; | 740 return; |
708 } | 741 } |
709 // Create the nexe file for connecting ld and sel_ldr. | 742 // Create the nexe file for connecting ld and sel_ldr. |
| 743 // Start translation when done with this last step of setup! |
710 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get())); | 744 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get())); |
711 pp::CompletionCallback cb = | 745 pp::CompletionCallback cb = |
712 callback_factory_.NewCallback(&PnaclCoordinator::NexeWriteDidOpen); | 746 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); |
713 nexe_file_->OpenWrite(cb); | 747 nexe_file_->OpenWrite(cb); |
714 } | 748 } |
715 | 749 |
716 void PnaclCoordinator::NexeWriteDidOpen(int32_t pp_error) { | |
717 PLUGIN_PRINTF(("PnaclCoordinator::NexeWriteDidOpen (pp_error=%" | |
718 NACL_PRId32")\n", pp_error)); | |
719 if (pp_error != PP_OK) { | |
720 ReportPpapiError(pp_error); | |
721 return; | |
722 } | |
723 // Load the pexe file and get the translation started. | |
724 pp::CompletionCallback cb = | |
725 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); | |
726 | |
727 if (!plugin_->StreamAsFile(pexe_url_, cb.pp_completion_callback())) { | |
728 ReportNonPpapiError(nacl::string("failed to download ") + pexe_url_ + "."); | |
729 } | |
730 } | |
731 | |
732 void PnaclCoordinator::RunTranslate(int32_t pp_error) { | 750 void PnaclCoordinator::RunTranslate(int32_t pp_error) { |
733 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" | 751 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" |
734 NACL_PRId32")\n", pp_error)); | 752 NACL_PRId32")\n", pp_error)); |
735 int32_t fd = GetLoadedFileDesc(pp_error, pexe_url_, "pexe"); | |
736 if (fd < 0) { | |
737 return; | |
738 } | |
739 pexe_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); | |
740 // Invoke llc followed by ld off the main thread. This allows use of | 753 // Invoke llc followed by ld off the main thread. This allows use of |
741 // blocking RPCs that would otherwise block the JavaScript main thread. | 754 // blocking RPCs that would otherwise block the JavaScript main thread. |
742 report_translate_finished_ = | 755 report_translate_finished_ = |
743 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); | 756 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); |
744 translate_thread_.reset(new NaClThread); | 757 translate_thread_.reset(new NaClThread); |
745 if (translate_thread_ == NULL) { | 758 if (translate_thread_ == NULL) { |
746 ReportNonPpapiError("could not allocate thread struct."); | 759 ReportNonPpapiError("could not allocate thread struct."); |
747 return; | 760 return; |
748 } | 761 } |
749 const int32_t kArbitraryStackSize = 128 * 1024; | 762 const int32_t kArbitraryStackSize = 128 * 1024; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 nacl::MutexLocker ml(&subprocess_mu_); | 863 nacl::MutexLocker ml(&subprocess_mu_); |
851 return subprocesses_should_die_; | 864 return subprocesses_should_die_; |
852 } | 865 } |
853 | 866 |
854 void PnaclCoordinator::SetSubprocessesShouldDie(bool subprocesses_should_die) { | 867 void PnaclCoordinator::SetSubprocessesShouldDie(bool subprocesses_should_die) { |
855 nacl::MutexLocker ml(&subprocess_mu_); | 868 nacl::MutexLocker ml(&subprocess_mu_); |
856 subprocesses_should_die_ = subprocesses_should_die; | 869 subprocesses_should_die_ = subprocesses_should_die; |
857 } | 870 } |
858 | 871 |
859 } // namespace plugin | 872 } // namespace plugin |
OLD | NEW |