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 "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" | 5 #include "ppapi/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/checked_cast.h" | 10 #include "native_client/src/include/checked_cast.h" |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 // before any scoped_* fields hanging off of PnaclCoordinator | 192 // before any scoped_* fields hanging off of PnaclCoordinator |
193 // since the thread may be accessing those fields. | 193 // since the thread may be accessing those fields. |
194 // It will also be accessing obj_files_. | 194 // It will also be accessing obj_files_. |
195 translate_thread_.reset(NULL); | 195 translate_thread_.reset(NULL); |
196 // TODO(jvoung): use base/memory/scoped_vector.h to hold obj_files_. | 196 // TODO(jvoung): use base/memory/scoped_vector.h to hold obj_files_. |
197 for (int i = 0; i < num_object_files_opened_; i++) { | 197 for (int i = 0; i < num_object_files_opened_; i++) { |
198 delete obj_files_[i]; | 198 delete obj_files_[i]; |
199 } | 199 } |
200 } | 200 } |
201 | 201 |
202 nacl::DescWrapper* PnaclCoordinator::ReleaseTranslatedFD() { | 202 PP_FileHandle PnaclCoordinator::TakeTranslatedFileHandle() { |
203 DCHECK(temp_nexe_file_ != NULL); | 203 DCHECK(temp_nexe_file_ != NULL); |
204 return temp_nexe_file_->release_read_wrapper(); | 204 return temp_nexe_file_->TakeFileHandle(); |
205 } | 205 } |
206 | 206 |
207 void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, | 207 void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, |
208 const nacl::string& message) { | 208 const nacl::string& message) { |
209 ErrorInfo error_info; | 209 ErrorInfo error_info; |
210 error_info.SetReport(err_code, message); | 210 error_info.SetReport(err_code, message); |
211 plugin_->ReportLoadError(error_info); | 211 plugin_->ReportLoadError(error_info); |
212 ExitWithError(); | 212 ExitWithError(); |
213 } | 213 } |
214 | 214 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 temp_nexe_file_->existing_handle(), | 433 temp_nexe_file_->existing_handle(), |
434 cb.pp_completion_callback()); | 434 cb.pp_completion_callback()); |
435 if (nexe_fd_err < PP_OK_COMPLETIONPENDING) { | 435 if (nexe_fd_err < PP_OK_COMPLETIONPENDING) { |
436 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, nexe_fd_err, | 436 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, nexe_fd_err, |
437 nacl::string("Call to GetNexeFd failed")); | 437 nacl::string("Call to GetNexeFd failed")); |
438 } | 438 } |
439 } | 439 } |
440 | 440 |
441 void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) { | 441 void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) { |
442 PLUGIN_PRINTF(("PnaclCoordinator::NexeFdDidOpen (pp_error=%" | 442 PLUGIN_PRINTF(("PnaclCoordinator::NexeFdDidOpen (pp_error=%" |
443 NACL_PRId32 ", hit=%d, handle=%d)\n", pp_error, | 443 NACL_PRId32 ", hit=%d)\n", pp_error, |
444 is_cache_hit_ == PP_TRUE, | 444 is_cache_hit_ == PP_TRUE)); |
445 *temp_nexe_file_->existing_handle())); | |
446 if (pp_error < PP_OK) { | 445 if (pp_error < PP_OK) { |
447 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, pp_error, | 446 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, pp_error, |
448 nacl::string("GetNexeFd failed")); | 447 nacl::string("GetNexeFd failed")); |
449 return; | 448 return; |
450 } | 449 } |
451 | 450 |
452 if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { | 451 if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { |
453 ReportNonPpapiError( | 452 ReportNonPpapiError( |
454 PP_NACL_ERROR_PNACL_CREATE_TEMP, | 453 PP_NACL_ERROR_PNACL_CREATE_TEMP, |
455 nacl::string( | 454 nacl::string( |
456 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); | 455 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); |
457 return; | 456 return; |
458 } | 457 } |
459 HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); | 458 HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); |
460 | 459 |
461 if (is_cache_hit_ == PP_TRUE) { | 460 if (is_cache_hit_ == PP_TRUE) { |
462 // Cache hit -- no need to stream the rest of the file. | 461 // Cache hit -- no need to stream the rest of the file. |
463 streaming_downloader_.reset(NULL); | 462 streaming_downloader_.reset(NULL); |
464 // Open it for reading as the cached nexe file. | 463 // Open it for reading as the cached nexe file. |
465 pp::CompletionCallback cb = | 464 NexeReadDidOpen(temp_nexe_file_->Open(false)); |
466 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); | |
467 temp_nexe_file_->Open(cb, false); | |
468 } else { | 465 } else { |
469 // Open an object file first so the translator can start writing to it | 466 // Open an object file first so the translator can start writing to it |
470 // during streaming translation. | 467 // during streaming translation. |
471 for (int i = 0; i < split_module_count_; i++) { | 468 for (int i = 0; i < split_module_count_; i++) { |
472 obj_files_.push_back(new TempFile(plugin_)); | 469 obj_files_.push_back(new TempFile(plugin_)); |
473 | 470 int32_t pp_error = obj_files_[i]->Open(true); |
474 pp::CompletionCallback obj_cb = | 471 if (pp_error != PP_OK) { |
475 callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileDidOpen); | 472 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, |
476 obj_files_[i]->Open(obj_cb, true); | 473 pp_error, |
| 474 "Failed to open scratch object file."); |
| 475 } else { |
| 476 num_object_files_opened_++; |
| 477 } |
477 } | 478 } |
478 invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid()); | 479 invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid()); |
479 | 480 |
480 // Meanwhile, a miss means we know we need to stream the bitcode, so stream | 481 // Meanwhile, a miss means we know we need to stream the bitcode, so stream |
481 // the rest of it now. (Calling FinishStreaming means that the downloader | 482 // the rest of it now. (Calling FinishStreaming means that the downloader |
482 // will begin handing data to the coordinator, which is safe any time after | 483 // will begin handing data to the coordinator, which is safe any time after |
483 // the translate_thread_ object has been initialized). | 484 // the translate_thread_ object has been initialized). |
484 pp::CompletionCallback finish_cb = callback_factory_.NewCallback( | 485 pp::CompletionCallback finish_cb = callback_factory_.NewCallback( |
485 &PnaclCoordinator::BitcodeStreamDidFinish); | 486 &PnaclCoordinator::BitcodeStreamDidFinish); |
486 streaming_downloader_->FinishStreaming(finish_cb); | 487 streaming_downloader_->FinishStreaming(finish_cb); |
| 488 |
| 489 if (num_object_files_opened_ == split_module_count_) { |
| 490 // Open the nexe file for connecting ld and sel_ldr. |
| 491 // Start translation when done with this last step of setup! |
| 492 RunTranslate(temp_nexe_file_->Open(true)); |
| 493 } |
487 } | 494 } |
488 } | 495 } |
489 | 496 |
490 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { | 497 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { |
491 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" | 498 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" |
492 NACL_PRId32 ")\n", pp_error)); | 499 NACL_PRId32 ")\n", pp_error)); |
493 if (pp_error != PP_OK) { | 500 if (pp_error != PP_OK) { |
494 // Defer reporting the error and cleanup until after the translation | 501 // Defer reporting the error and cleanup until after the translation |
495 // thread returns, because it may be accessing the coordinator's | 502 // thread returns, because it may be accessing the coordinator's |
496 // objects or writing to the files. | 503 // objects or writing to the files. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 event_name, | 590 event_name, |
584 microsecs); | 591 microsecs); |
585 } | 592 } |
586 | 593 |
587 void PnaclCoordinator::GetCurrentProgress(int64_t* bytes_loaded, | 594 void PnaclCoordinator::GetCurrentProgress(int64_t* bytes_loaded, |
588 int64_t* bytes_total) { | 595 int64_t* bytes_total) { |
589 *bytes_loaded = pexe_bytes_compiled_; | 596 *bytes_loaded = pexe_bytes_compiled_; |
590 *bytes_total = expected_pexe_size_; | 597 *bytes_total = expected_pexe_size_; |
591 } | 598 } |
592 | 599 |
593 void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { | |
594 PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileDidOpen (pp_error=%" | |
595 NACL_PRId32 ")\n", pp_error)); | |
596 if (pp_error != PP_OK) { | |
597 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, | |
598 pp_error, | |
599 "Failed to open scratch object file."); | |
600 return; | |
601 } | |
602 num_object_files_opened_++; | |
603 if (num_object_files_opened_ == split_module_count_) { | |
604 // Open the nexe file for connecting ld and sel_ldr. | |
605 // Start translation when done with this last step of setup! | |
606 pp::CompletionCallback cb = | |
607 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); | |
608 temp_nexe_file_->Open(cb, true); | |
609 } | |
610 } | |
611 | |
612 void PnaclCoordinator::RunTranslate(int32_t pp_error) { | 600 void PnaclCoordinator::RunTranslate(int32_t pp_error) { |
613 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" | 601 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" |
614 NACL_PRId32 ")\n", pp_error)); | 602 NACL_PRId32 ")\n", pp_error)); |
615 // Invoke llc followed by ld off the main thread. This allows use of | 603 // Invoke llc followed by ld off the main thread. This allows use of |
616 // blocking RPCs that would otherwise block the JavaScript main thread. | 604 // blocking RPCs that would otherwise block the JavaScript main thread. |
617 pp::CompletionCallback report_translate_finished = | 605 pp::CompletionCallback report_translate_finished = |
618 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); | 606 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); |
619 | 607 |
620 CHECK(translate_thread_ != NULL); | 608 CHECK(translate_thread_ != NULL); |
621 translate_thread_->RunTranslate(report_translate_finished, | 609 translate_thread_->RunTranslate(report_translate_finished, |
622 manifest_id_, | 610 manifest_id_, |
623 &obj_files_, | 611 &obj_files_, |
624 temp_nexe_file_.get(), | 612 temp_nexe_file_.get(), |
625 invalid_desc_wrapper_.get(), | 613 invalid_desc_wrapper_.get(), |
626 &error_info_, | 614 &error_info_, |
627 resources_.get(), | 615 resources_.get(), |
628 &pnacl_options_, | 616 &pnacl_options_, |
629 architecture_attributes_, | 617 architecture_attributes_, |
630 this, | 618 this, |
631 plugin_); | 619 plugin_); |
632 } | 620 } |
633 | 621 |
634 } // namespace plugin | 622 } // namespace plugin |
OLD | NEW |