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

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: rebased 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698