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

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

Issue 276423003: Pepper: Nexe downloading out of the trusted plugin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add PlatformFile include Created 6 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 #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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 // Up to 20 seconds 54 // Up to 20 seconds
55 const int64_t kTimeSmallMin = 1; // in ms 55 const int64_t kTimeSmallMin = 1; // in ms
56 const int64_t kTimeSmallMax = 20000; // in ms 56 const int64_t kTimeSmallMax = 20000; // in ms
57 const uint32_t kTimeSmallBuckets = 100; 57 const uint32_t kTimeSmallBuckets = 100;
58 58
59 const int64_t kSizeKBMin = 1; 59 const int64_t kSizeKBMin = 1;
60 const int64_t kSizeKBMax = 512*1024; // very large .nexe 60 const int64_t kSizeKBMax = 512*1024; // very large .nexe
61 const uint32_t kSizeKBBuckets = 100; 61 const uint32_t kSizeKBBuckets = 100;
62 62
63 // Converts a PP_FileHandle to a POSIX file descriptor.
64 int32_t ConvertFileDescriptor(PP_FileHandle handle) {
65 PLUGIN_PRINTF(("ConvertFileDescriptor, handle=%d\n", handle));
66 #if NACL_WINDOWS
67 int32_t file_desc = NACL_NO_FILE_DESC;
68 // On Windows, valid handles are 32 bit unsigned integers so this is safe.
69 file_desc = reinterpret_cast<uintptr_t>(handle);
70 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor.
71 int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY);
72 if (posix_desc == -1) {
73 // Close the Windows HANDLE if it can't be converted.
74 CloseHandle(reinterpret_cast<HANDLE>(file_desc));
75 return -1;
76 }
77 return posix_desc;
78 #else
79 return handle;
80 #endif
81 }
82
83
63 } // namespace 84 } // namespace
64 85
65 void Plugin::ShutDownSubprocesses() { 86 void Plugin::ShutDownSubprocesses() {
66 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", 87 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n",
67 static_cast<void*>(this))); 88 static_cast<void*>(this)));
68 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", 89 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n",
69 main_subprocess_.detailed_description().c_str())); 90 main_subprocess_.detailed_description().c_str()));
70 91
71 // Shut down service runtime. This must be done before all other calls so 92 // Shut down service runtime. This must be done before all other calls so
72 // they don't block forever when waiting for the upcall thread to exit. 93 // they don't block forever when waiting for the upcall thread to exit.
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 RequestNaClManifest(manifest_url.AsString()); 382 RequestNaClManifest(manifest_url.AsString());
362 return true; 383 return true;
363 } 384 }
364 385
365 Plugin::Plugin(PP_Instance pp_instance) 386 Plugin::Plugin(PP_Instance pp_instance)
366 : pp::Instance(pp_instance), 387 : pp::Instance(pp_instance),
367 main_subprocess_("main subprocess", NULL, NULL), 388 main_subprocess_("main subprocess", NULL, NULL),
368 uses_nonsfi_mode_(false), 389 uses_nonsfi_mode_(false),
369 wrapper_factory_(NULL), 390 wrapper_factory_(NULL),
370 time_of_last_progress_event_(0), 391 time_of_last_progress_event_(0),
371 nexe_open_time_(-1),
372 manifest_id_(-1), 392 manifest_id_(-1),
393 nexe_handle_(PP_kInvalidFileHandle),
373 nacl_interface_(NULL), 394 nacl_interface_(NULL),
374 uma_interface_(this) { 395 uma_interface_(this) {
375 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" 396 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%"
376 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); 397 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance));
377 callback_factory_.Initialize(this); 398 callback_factory_.Initialize(this);
378 nexe_downloader_.Initialize(this);
379 nacl_interface_ = GetNaClInterface(); 399 nacl_interface_ = GetNaClInterface();
380 CHECK(nacl_interface_ != NULL); 400 CHECK(nacl_interface_ != NULL);
381 401
382 // Notify PPB_NaCl_Private that the instance is created before altering any 402 // Notify PPB_NaCl_Private that the instance is created before altering any
383 // state that it tracks. 403 // state that it tracks.
384 nacl_interface_->InstanceCreated(pp_instance); 404 nacl_interface_->InstanceCreated(pp_instance);
385 // We call set_exit_status() here to ensure that the 'exitStatus' property is 405 // We call set_exit_status() here to ensure that the 'exitStatus' property is
386 // set. This can only be called when nacl_interface_ is not NULL. 406 // set. This can only be called when nacl_interface_ is not NULL.
387 set_exit_status(-1); 407 set_exit_status(-1);
388 } 408 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 466
447 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { 467 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) {
448 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", 468 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n",
449 static_cast<void*>(this))); 469 static_cast<void*>(this)));
450 // We don't know if the plugin will handle the document load, but return 470 // We don't know if the plugin will handle the document load, but return
451 // true in order to give it a chance to respond once the proxy is started. 471 // true in order to give it a chance to respond once the proxy is started.
452 return true; 472 return true;
453 } 473 }
454 474
455 void Plugin::NexeFileDidOpen(int32_t pp_error) { 475 void Plugin::NexeFileDidOpen(int32_t pp_error) {
456 NaClFileInfo tmp_info(nexe_downloader_.GetFileInfo()); 476 if (pp_error != PP_OK)
457 NaClFileInfoAutoCloser info(&tmp_info);
458
459 int64_t nexe_bytes_read = -1;
460 if (pp_error == PP_OK && info.get_desc() != NACL_NO_FILE_DESC) {
461 struct stat stat_buf;
462 if (0 == fstat(info.get_desc(), &stat_buf))
463 nexe_bytes_read = stat_buf.st_size;
464 }
465
466 int64_t now = NaClGetTimeOfDayMicroseconds();
467 int64_t download_time;
468 if (now < nexe_open_time_)
469 download_time = 0;
470 else
471 download_time = now - nexe_open_time_;
472
473 nacl_interface_->NexeFileDidOpen(
474 pp_instance(),
475 pp_error,
476 info.get_desc(),
477 nexe_downloader_.status_code(),
478 nexe_bytes_read,
479 nexe_downloader_.url().c_str(),
480 download_time / 1000);
481
482 if (nexe_bytes_read == -1)
483 return; 477 return;
484 478
479 int32_t desc = ConvertFileDescriptor(nexe_handle_);
480 nexe_handle_ = PP_kInvalidFileHandle; // Clear out nexe handle.
481
485 nacl::scoped_ptr<nacl::DescWrapper> 482 nacl::scoped_ptr<nacl::DescWrapper>
486 wrapper(wrapper_factory()->MakeFileDesc(info.Release().desc, O_RDONLY)); 483 wrapper(wrapper_factory()->MakeFileDesc(desc, O_RDONLY));
487 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); 484 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n");
488 LoadNaClModule( 485 LoadNaClModule(
489 wrapper.release(), 486 wrapper.release(),
490 uses_nonsfi_mode_, 487 uses_nonsfi_mode_,
491 true, /* enable_dyncode_syscalls */ 488 true, /* enable_dyncode_syscalls */
492 true, /* enable_exception_handling */ 489 true, /* enable_exception_handling */
493 false, /* enable_crash_throttling */ 490 false, /* enable_crash_throttling */
494 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation), 491 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation),
495 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); 492 callback_factory_.NewCallback(&Plugin::NexeDidCrash));
496 } 493 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 HistogramSizeKB("NaCl.Perf.Size.Manifest", 575 HistogramSizeKB("NaCl.Perf.Size.Manifest",
579 static_cast<int32_t>(manifest_json.length() / 1024)); 576 static_cast<int32_t>(manifest_json.length() / 1024));
580 if (!SetManifestObject(manifest_json)) 577 if (!SetManifestObject(manifest_json))
581 return; 578 return;
582 579
583 PP_Var pp_program_url; 580 PP_Var pp_program_url;
584 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; 581 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
585 PP_Bool uses_nonsfi_mode; 582 PP_Bool uses_nonsfi_mode;
586 if (nacl_interface_->GetManifestProgramURL(pp_instance(), 583 if (nacl_interface_->GetManifestProgramURL(pp_instance(),
587 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { 584 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) {
588 std::string program_url = pp::Var(pp::PASS_REF, pp_program_url).AsString(); 585 program_url_ = pp::Var(pp::PASS_REF, pp_program_url).AsString();
589 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of 586 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of
590 // this function. 587 // this function.
591 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str()); 588 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url_.c_str());
592 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); 589 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode);
593 if (pnacl_options.translate) { 590 if (pnacl_options.translate) {
594 pp::CompletionCallback translate_callback = 591 pp::CompletionCallback translate_callback =
595 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); 592 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate);
596 pnacl_coordinator_.reset( 593 pnacl_coordinator_.reset(
597 PnaclCoordinator::BitcodeToNative(this, 594 PnaclCoordinator::BitcodeToNative(this,
598 program_url, 595 program_url_,
599 pnacl_options, 596 pnacl_options,
600 translate_callback)); 597 translate_callback));
601 return; 598 return;
602 } else { 599 } else {
603 nexe_open_time_ = NaClGetTimeOfDayMicroseconds(); 600 pp::CompletionCallback open_callback =
604 // Try the fast path first. This will only block if the file is installed. 601 callback_factory_.NewCallback(&Plugin::NexeFileDidOpen);
605 if (OpenURLFast(program_url, &nexe_downloader_)) { 602 // Will always call the callback on success or failure.
606 NexeFileDidOpen(PP_OK); 603 nacl_interface_->DownloadNexe(pp_instance(),
607 } else { 604 program_url_.c_str(),
608 pp::CompletionCallback open_callback = 605 &nexe_handle_,
609 callback_factory_.NewCallback(&Plugin::NexeFileDidOpen); 606 open_callback.pp_completion_callback());
610 // Will always call the callback on success or failure.
611 CHECK(
612 nexe_downloader_.Open(program_url,
613 DOWNLOAD_TO_FILE,
614 open_callback,
615 true,
616 &UpdateDownloadProgress));
617 }
618 return; 607 return;
619 } 608 }
620 } 609 }
621 } 610 }
622 611
623 void Plugin::RequestNaClManifest(const nacl::string& url) { 612 void Plugin::RequestNaClManifest(const nacl::string& url) {
624 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); 613 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str()));
625 PP_Bool is_data_uri; 614 PP_Bool is_data_uri;
626 ErrorInfo error_info; 615 ErrorInfo error_info;
627 if (!nacl_interface_->RequestNaClManifest(pp_instance(), url.c_str(), 616 if (!nacl_interface_->RequestNaClManifest(pp_instance(), url.c_str(),
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 // If true, will always call the callback on success or failure. 733 // If true, will always call the callback on success or failure.
745 return downloader->Open(url, 734 return downloader->Open(url,
746 DOWNLOAD_TO_FILE, 735 DOWNLOAD_TO_FILE,
747 open_callback, 736 open_callback,
748 true, 737 true,
749 &UpdateDownloadProgress); 738 &UpdateDownloadProgress);
750 } 739 }
751 740
752 741
753 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) { 742 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) {
754 const nacl::string& url = nexe_downloader_.url();
755 nacl_interface_->ReportLoadSuccess( 743 nacl_interface_->ReportLoadSuccess(
756 pp_instance(), url.c_str(), loaded_bytes, total_bytes); 744 pp_instance(), program_url_.c_str(), loaded_bytes, total_bytes);
757 } 745 }
758 746
759 747
760 void Plugin::ReportLoadError(const ErrorInfo& error_info) { 748 void Plugin::ReportLoadError(const ErrorInfo& error_info) {
761 nacl_interface_->ReportLoadError(pp_instance(), 749 nacl_interface_->ReportLoadError(pp_instance(),
762 error_info.error_code(), 750 error_info.error_code(),
763 error_info.message().c_str(), 751 error_info.message().c_str(),
764 error_info.console_message().c_str()); 752 error_info.console_message().c_str());
765 } 753 }
766 754
(...skipping 15 matching lines...) Expand all
782 // Rate limit progress events to a maximum of 100 per second. 770 // Rate limit progress events to a maximum of 100 per second.
783 int64_t time = NaClGetTimeOfDayMicroseconds(); 771 int64_t time = NaClGetTimeOfDayMicroseconds();
784 int64_t elapsed = time - plugin->time_of_last_progress_event_; 772 int64_t elapsed = time - plugin->time_of_last_progress_event_;
785 const int64_t kTenMilliseconds = 10000; 773 const int64_t kTenMilliseconds = 10000;
786 if (elapsed > kTenMilliseconds) { 774 if (elapsed > kTenMilliseconds) {
787 plugin->time_of_last_progress_event_ = time; 775 plugin->time_of_last_progress_event_ = time;
788 776
789 // Find the URL loader that sent this notification. 777 // Find the URL loader that sent this notification.
790 const FileDownloader* file_downloader = 778 const FileDownloader* file_downloader =
791 plugin->FindFileDownloader(pp_resource); 779 plugin->FindFileDownloader(pp_resource);
792 // If not a streamed file, it must be the .nexe loader. 780 nacl::string url;
793 if (file_downloader == NULL) 781 if (file_downloader)
794 file_downloader = &plugin->nexe_downloader_; 782 url = file_downloader->url();
795 nacl::string url = file_downloader->url();
796 LengthComputable length_computable = (total_bytes_to_be_received >= 0) ? 783 LengthComputable length_computable = (total_bytes_to_be_received >= 0) ?
797 LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE; 784 LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE;
798 785
799 plugin->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, 786 plugin->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS,
800 url, 787 url,
801 length_computable, 788 length_computable,
802 bytes_received, 789 bytes_received,
803 total_bytes_to_be_received); 790 total_bytes_to_be_received);
804 } 791 }
805 } 792 }
806 } 793 }
807 794
808 const FileDownloader* Plugin::FindFileDownloader( 795 const FileDownloader* Plugin::FindFileDownloader(
809 PP_Resource url_loader) const { 796 PP_Resource url_loader) const {
810 const FileDownloader* file_downloader = NULL; 797 const FileDownloader* file_downloader = NULL;
811 if (url_loader == nexe_downloader_.url_loader()) { 798 std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin();
812 file_downloader = &nexe_downloader_; 799 while (it != url_downloaders_.end()) {
813 } else { 800 if (url_loader == (*it)->url_loader()) {
814 std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin(); 801 file_downloader = (*it);
815 while (it != url_downloaders_.end()) { 802 break;
816 if (url_loader == (*it)->url_loader()) {
817 file_downloader = (*it);
818 break;
819 }
820 ++it;
821 } 803 }
804 ++it;
822 } 805 }
823 return file_downloader; 806 return file_downloader;
824 } 807 }
825 808
826 void Plugin::ReportSelLdrLoadStatus(int status) { 809 void Plugin::ReportSelLdrLoadStatus(int status) {
827 HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status)); 810 HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status));
828 } 811 }
829 812
830 void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type, 813 void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type,
831 const nacl::string& url, 814 const nacl::string& url,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 870
888 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, 871 void Plugin::SetExitStatusOnMainThread(int32_t pp_error,
889 int exit_status) { 872 int exit_status) {
890 DCHECK(pp::Module::Get()->core()->IsMainThread()); 873 DCHECK(pp::Module::Get()->core()->IsMainThread());
891 DCHECK(nacl_interface_); 874 DCHECK(nacl_interface_);
892 nacl_interface_->SetExitStatus(pp_instance(), exit_status); 875 nacl_interface_->SetExitStatus(pp_instance(), exit_status);
893 } 876 }
894 877
895 878
896 } // namespace plugin 879 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698