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 #ifdef _MSC_VER | 5 #ifdef _MSC_VER |
6 // Do not warn about use of std::copy with raw pointers. | 6 // Do not warn about use of std::copy with raw pointers. |
7 #pragma warning(disable : 4996) | 7 #pragma warning(disable : 4996) |
8 #endif | 8 #endif |
9 | 9 |
10 #include "ppapi/native_client/src/trusted/plugin/plugin.h" | 10 #include "ppapi/native_client/src/trusted/plugin/plugin.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 | 51 |
52 // Up to 20 seconds | 52 // Up to 20 seconds |
53 const int64_t kTimeSmallMin = 1; // in ms | 53 const int64_t kTimeSmallMin = 1; // in ms |
54 const int64_t kTimeSmallMax = 20000; // in ms | 54 const int64_t kTimeSmallMax = 20000; // in ms |
55 const uint32_t kTimeSmallBuckets = 100; | 55 const uint32_t kTimeSmallBuckets = 100; |
56 | 56 |
57 const int64_t kSizeKBMin = 1; | 57 const int64_t kSizeKBMin = 1; |
58 const int64_t kSizeKBMax = 512*1024; // very large .nexe | 58 const int64_t kSizeKBMax = 512*1024; // very large .nexe |
59 const uint32_t kSizeKBBuckets = 100; | 59 const uint32_t kSizeKBBuckets = 100; |
60 | 60 |
61 // Converts a PP_FileHandle to a POSIX file descriptor. | |
62 int32_t ConvertFileDescriptor(PP_FileHandle handle) { | |
63 PLUGIN_PRINTF(("ConvertFileDescriptor, handle=%d\n", handle)); | |
64 #if NACL_WINDOWS | |
65 int32_t file_desc = NACL_NO_FILE_DESC; | |
66 // On Windows, valid handles are 32 bit unsigned integers so this is safe. | |
67 file_desc = reinterpret_cast<uintptr_t>(handle); | |
bbudge
2014/05/14 21:46:18
I did a little code search, and everywhere else we
teravest
2014/05/15 19:12:21
Done.
| |
68 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor. | |
69 int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY); | |
70 if (posix_desc == -1) { | |
71 // Close the Windows HANDLE if it can't be converted. | |
72 CloseHandle(reinterpret_cast<HANDLE>(file_desc)); | |
73 return -1; | |
74 } | |
75 return posix_desc; | |
76 #else | |
77 return handle; | |
78 #endif | |
79 } | |
80 | |
81 | |
61 } // namespace | 82 } // namespace |
62 | 83 |
63 void Plugin::ShutDownSubprocesses() { | 84 void Plugin::ShutDownSubprocesses() { |
64 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", | 85 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", |
65 static_cast<void*>(this))); | 86 static_cast<void*>(this))); |
66 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", | 87 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", |
67 main_subprocess_.detailed_description().c_str())); | 88 main_subprocess_.detailed_description().c_str())); |
68 | 89 |
69 // Shut down service runtime. This must be done before all other calls so | 90 // Shut down service runtime. This must be done before all other calls so |
70 // they don't block forever when waiting for the upcall thread to exit. | 91 // they don't block forever when waiting for the upcall thread to exit. |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 RequestNaClManifest(manifest_url.AsString()); | 357 RequestNaClManifest(manifest_url.AsString()); |
337 return true; | 358 return true; |
338 } | 359 } |
339 | 360 |
340 Plugin::Plugin(PP_Instance pp_instance) | 361 Plugin::Plugin(PP_Instance pp_instance) |
341 : pp::Instance(pp_instance), | 362 : pp::Instance(pp_instance), |
342 main_subprocess_("main subprocess", NULL, NULL), | 363 main_subprocess_("main subprocess", NULL, NULL), |
343 uses_nonsfi_mode_(false), | 364 uses_nonsfi_mode_(false), |
344 wrapper_factory_(NULL), | 365 wrapper_factory_(NULL), |
345 time_of_last_progress_event_(0), | 366 time_of_last_progress_event_(0), |
346 nexe_open_time_(-1), | |
347 manifest_id_(-1), | 367 manifest_id_(-1), |
368 nexe_handle_(PP_kInvalidFileHandle), | |
348 nacl_interface_(NULL), | 369 nacl_interface_(NULL), |
349 uma_interface_(this) { | 370 uma_interface_(this) { |
350 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" | 371 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" |
351 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); | 372 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); |
352 callback_factory_.Initialize(this); | 373 callback_factory_.Initialize(this); |
353 nexe_downloader_.Initialize(this); | |
354 nacl_interface_ = GetNaClInterface(); | 374 nacl_interface_ = GetNaClInterface(); |
355 CHECK(nacl_interface_ != NULL); | 375 CHECK(nacl_interface_ != NULL); |
356 | 376 |
357 // Notify PPB_NaCl_Private that the instance is created before altering any | 377 // Notify PPB_NaCl_Private that the instance is created before altering any |
358 // state that it tracks. | 378 // state that it tracks. |
359 nacl_interface_->InstanceCreated(pp_instance); | 379 nacl_interface_->InstanceCreated(pp_instance); |
360 // We call set_exit_status() here to ensure that the 'exitStatus' property is | 380 // We call set_exit_status() here to ensure that the 'exitStatus' property is |
361 // set. This can only be called when nacl_interface_ is not NULL. | 381 // set. This can only be called when nacl_interface_ is not NULL. |
362 set_exit_status(-1); | 382 set_exit_status(-1); |
363 } | 383 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 | 441 |
422 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { | 442 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { |
423 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", | 443 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", |
424 static_cast<void*>(this))); | 444 static_cast<void*>(this))); |
425 // We don't know if the plugin will handle the document load, but return | 445 // We don't know if the plugin will handle the document load, but return |
426 // true in order to give it a chance to respond once the proxy is started. | 446 // true in order to give it a chance to respond once the proxy is started. |
427 return true; | 447 return true; |
428 } | 448 } |
429 | 449 |
430 void Plugin::NexeFileDidOpen(int32_t pp_error) { | 450 void Plugin::NexeFileDidOpen(int32_t pp_error) { |
431 NaClFileInfo tmp_info(nexe_downloader_.GetFileInfo()); | 451 if (pp_error != PP_OK) |
432 NaClFileInfoAutoCloser info(&tmp_info); | |
433 | |
434 int64_t nexe_bytes_read = -1; | |
435 if (pp_error == PP_OK && info.get_desc() != NACL_NO_FILE_DESC) { | |
436 struct stat stat_buf; | |
437 if (0 == fstat(info.get_desc(), &stat_buf)) | |
438 nexe_bytes_read = stat_buf.st_size; | |
439 } | |
440 | |
441 int64_t now = NaClGetTimeOfDayMicroseconds(); | |
442 int64_t download_time; | |
443 if (now < nexe_open_time_) | |
444 download_time = 0; | |
445 else | |
446 download_time = now - nexe_open_time_; | |
447 | |
448 nacl_interface_->NexeFileDidOpen( | |
449 pp_instance(), | |
450 pp_error, | |
451 info.get_desc(), | |
452 nexe_downloader_.status_code(), | |
453 nexe_bytes_read, | |
454 nexe_downloader_.url().c_str(), | |
455 download_time / 1000); | |
456 | |
457 if (nexe_bytes_read == -1) | |
458 return; | 452 return; |
459 | 453 |
454 int32_t desc = ConvertFileDescriptor(nexe_handle_); | |
455 nexe_handle_ = PP_kInvalidFileHandle; // Clear out nexe handle. | |
456 | |
460 nacl::scoped_ptr<nacl::DescWrapper> | 457 nacl::scoped_ptr<nacl::DescWrapper> |
461 wrapper(wrapper_factory()->MakeFileDesc(info.Release().desc, O_RDONLY)); | 458 wrapper(wrapper_factory()->MakeFileDesc(desc, O_RDONLY)); |
462 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); | 459 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); |
463 LoadNaClModule( | 460 LoadNaClModule( |
464 wrapper.release(), | 461 wrapper.release(), |
465 uses_nonsfi_mode_, | 462 uses_nonsfi_mode_, |
466 true, /* enable_dyncode_syscalls */ | 463 true, /* enable_dyncode_syscalls */ |
467 true, /* enable_exception_handling */ | 464 true, /* enable_exception_handling */ |
468 false, /* enable_crash_throttling */ | 465 false, /* enable_crash_throttling */ |
469 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation), | 466 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation), |
470 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); | 467 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); |
471 } | 468 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 HistogramSizeKB("NaCl.Perf.Size.Manifest", | 551 HistogramSizeKB("NaCl.Perf.Size.Manifest", |
555 static_cast<int32_t>(manifest_json.length() / 1024)); | 552 static_cast<int32_t>(manifest_json.length() / 1024)); |
556 if (!SetManifestObject(manifest_json)) | 553 if (!SetManifestObject(manifest_json)) |
557 return; | 554 return; |
558 | 555 |
559 PP_Var pp_program_url; | 556 PP_Var pp_program_url; |
560 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; | 557 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; |
561 PP_Bool uses_nonsfi_mode; | 558 PP_Bool uses_nonsfi_mode; |
562 if (nacl_interface_->GetManifestProgramURL(pp_instance(), | 559 if (nacl_interface_->GetManifestProgramURL(pp_instance(), |
563 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { | 560 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { |
564 std::string program_url = pp::Var(pp::PASS_REF, pp_program_url).AsString(); | 561 program_url_ = pp::Var(pp::PASS_REF, pp_program_url).AsString(); |
565 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of | 562 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of |
566 // this function. | 563 // this function. |
567 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str()); | 564 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url_.c_str()); |
568 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); | 565 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); |
569 if (pnacl_options.translate) { | 566 if (pnacl_options.translate) { |
570 pp::CompletionCallback translate_callback = | 567 pp::CompletionCallback translate_callback = |
571 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); | 568 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); |
572 pnacl_coordinator_.reset( | 569 pnacl_coordinator_.reset( |
573 PnaclCoordinator::BitcodeToNative(this, | 570 PnaclCoordinator::BitcodeToNative(this, |
574 program_url, | 571 program_url_, |
575 pnacl_options, | 572 pnacl_options, |
576 translate_callback)); | 573 translate_callback)); |
577 return; | 574 return; |
578 } else { | 575 } else { |
579 nexe_open_time_ = NaClGetTimeOfDayMicroseconds(); | 576 pp::CompletionCallback open_callback = |
580 // Try the fast path first. This will only block if the file is installed. | 577 callback_factory_.NewCallback(&Plugin::NexeFileDidOpen); |
581 if (OpenURLFast(program_url, &nexe_downloader_)) { | 578 // Will always call the callback on success or failure. |
582 NexeFileDidOpen(PP_OK); | 579 nacl_interface_->DownloadNexe(pp_instance(), |
583 } else { | 580 program_url_.c_str(), |
584 pp::CompletionCallback open_callback = | 581 &nexe_handle_, |
585 callback_factory_.NewCallback(&Plugin::NexeFileDidOpen); | 582 open_callback.pp_completion_callback()); |
586 // Will always call the callback on success or failure. | |
587 CHECK( | |
588 nexe_downloader_.Open(program_url, | |
589 DOWNLOAD_TO_FILE, | |
590 open_callback, | |
591 true, | |
592 &UpdateDownloadProgress)); | |
593 } | |
594 return; | 583 return; |
595 } | 584 } |
596 } | 585 } |
597 } | 586 } |
598 | 587 |
599 void Plugin::RequestNaClManifest(const nacl::string& url) { | 588 void Plugin::RequestNaClManifest(const nacl::string& url) { |
600 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); | 589 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); |
601 PP_Bool is_data_uri; | 590 PP_Bool is_data_uri; |
602 ErrorInfo error_info; | 591 ErrorInfo error_info; |
603 if (!nacl_interface_->RequestNaClManifest(pp_instance(), url.c_str(), | 592 if (!nacl_interface_->RequestNaClManifest(pp_instance(), url.c_str(), |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 // If true, will always call the callback on success or failure. | 706 // If true, will always call the callback on success or failure. |
718 return downloader->Open(url, | 707 return downloader->Open(url, |
719 DOWNLOAD_TO_FILE, | 708 DOWNLOAD_TO_FILE, |
720 open_callback, | 709 open_callback, |
721 true, | 710 true, |
722 &UpdateDownloadProgress); | 711 &UpdateDownloadProgress); |
723 } | 712 } |
724 | 713 |
725 | 714 |
726 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) { | 715 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) { |
727 const nacl::string& url = nexe_downloader_.url(); | |
728 nacl_interface_->ReportLoadSuccess( | 716 nacl_interface_->ReportLoadSuccess( |
729 pp_instance(), url.c_str(), loaded_bytes, total_bytes); | 717 pp_instance(), program_url_.c_str(), loaded_bytes, total_bytes); |
730 } | 718 } |
731 | 719 |
732 | 720 |
733 void Plugin::ReportLoadError(const ErrorInfo& error_info) { | 721 void Plugin::ReportLoadError(const ErrorInfo& error_info) { |
734 nacl_interface_->ReportLoadError(pp_instance(), | 722 nacl_interface_->ReportLoadError(pp_instance(), |
735 error_info.error_code(), | 723 error_info.error_code(), |
736 error_info.message().c_str(), | 724 error_info.message().c_str(), |
737 error_info.console_message().c_str()); | 725 error_info.console_message().c_str()); |
738 } | 726 } |
739 | 727 |
(...skipping 15 matching lines...) Expand all Loading... | |
755 // Rate limit progress events to a maximum of 100 per second. | 743 // Rate limit progress events to a maximum of 100 per second. |
756 int64_t time = NaClGetTimeOfDayMicroseconds(); | 744 int64_t time = NaClGetTimeOfDayMicroseconds(); |
757 int64_t elapsed = time - plugin->time_of_last_progress_event_; | 745 int64_t elapsed = time - plugin->time_of_last_progress_event_; |
758 const int64_t kTenMilliseconds = 10000; | 746 const int64_t kTenMilliseconds = 10000; |
759 if (elapsed > kTenMilliseconds) { | 747 if (elapsed > kTenMilliseconds) { |
760 plugin->time_of_last_progress_event_ = time; | 748 plugin->time_of_last_progress_event_ = time; |
761 | 749 |
762 // Find the URL loader that sent this notification. | 750 // Find the URL loader that sent this notification. |
763 const FileDownloader* file_downloader = | 751 const FileDownloader* file_downloader = |
764 plugin->FindFileDownloader(pp_resource); | 752 plugin->FindFileDownloader(pp_resource); |
765 // If not a streamed file, it must be the .nexe loader. | 753 nacl::string url; |
766 if (file_downloader == NULL) | 754 if (file_downloader) |
767 file_downloader = &plugin->nexe_downloader_; | 755 url = file_downloader->url(); |
768 nacl::string url = file_downloader->url(); | |
769 LengthComputable length_computable = (total_bytes_to_be_received >= 0) ? | 756 LengthComputable length_computable = (total_bytes_to_be_received >= 0) ? |
770 LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE; | 757 LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE; |
771 | 758 |
772 plugin->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, | 759 plugin->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, |
773 url, | 760 url, |
774 length_computable, | 761 length_computable, |
775 bytes_received, | 762 bytes_received, |
776 total_bytes_to_be_received); | 763 total_bytes_to_be_received); |
777 } | 764 } |
778 } | 765 } |
779 } | 766 } |
780 | 767 |
781 const FileDownloader* Plugin::FindFileDownloader( | 768 const FileDownloader* Plugin::FindFileDownloader( |
782 PP_Resource url_loader) const { | 769 PP_Resource url_loader) const { |
783 const FileDownloader* file_downloader = NULL; | 770 const FileDownloader* file_downloader = NULL; |
784 if (url_loader == nexe_downloader_.url_loader()) { | 771 std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin(); |
785 file_downloader = &nexe_downloader_; | 772 while (it != url_downloaders_.end()) { |
bbudge
2014/05/14 21:46:18
Since we're eliminating the special handling of ne
teravest
2014/05/15 19:12:21
I tested with Angry bots, it loaded and ran fine.
| |
786 } else { | 773 if (url_loader == (*it)->url_loader()) { |
787 std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin(); | 774 file_downloader = (*it); |
788 while (it != url_downloaders_.end()) { | 775 break; |
789 if (url_loader == (*it)->url_loader()) { | |
790 file_downloader = (*it); | |
791 break; | |
792 } | |
793 ++it; | |
794 } | 776 } |
777 ++it; | |
795 } | 778 } |
796 return file_downloader; | 779 return file_downloader; |
797 } | 780 } |
798 | 781 |
799 void Plugin::ReportSelLdrLoadStatus(int status) { | 782 void Plugin::ReportSelLdrLoadStatus(int status) { |
800 HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status)); | 783 HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status)); |
801 } | 784 } |
802 | 785 |
803 void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type, | 786 void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type, |
804 const nacl::string& url, | 787 const nacl::string& url, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
860 | 843 |
861 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, | 844 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, |
862 int exit_status) { | 845 int exit_status) { |
863 DCHECK(pp::Module::Get()->core()->IsMainThread()); | 846 DCHECK(pp::Module::Get()->core()->IsMainThread()); |
864 DCHECK(nacl_interface_); | 847 DCHECK(nacl_interface_); |
865 nacl_interface_->SetExitStatus(pp_instance(), exit_status); | 848 nacl_interface_->SetExitStatus(pp_instance(), exit_status); |
866 } | 849 } |
867 | 850 |
868 | 851 |
869 } // namespace plugin | 852 } // namespace plugin |
OLD | NEW |