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

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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 46
47 // Up to 20 seconds 47 // Up to 20 seconds
48 const int64_t kTimeSmallMin = 1; // in ms 48 const int64_t kTimeSmallMin = 1; // in ms
49 const int64_t kTimeSmallMax = 20000; // in ms 49 const int64_t kTimeSmallMax = 20000; // in ms
50 const uint32_t kTimeSmallBuckets = 100; 50 const uint32_t kTimeSmallBuckets = 100;
51 51
52 const int64_t kSizeKBMin = 1; 52 const int64_t kSizeKBMin = 1;
53 const int64_t kSizeKBMax = 512*1024; // very large .nexe 53 const int64_t kSizeKBMax = 512*1024; // very large .nexe
54 const uint32_t kSizeKBBuckets = 100; 54 const uint32_t kSizeKBBuckets = 100;
55 55
56 // Converts a PP_FileHandle to a POSIX file descriptor.
57 int32_t ConvertFileDescriptor(PP_FileHandle handle) {
58 PLUGIN_PRINTF(("ConvertFileDescriptor, handle=%d\n", handle));
59 #if NACL_WINDOWS
60 int32_t file_desc = NACL_NO_FILE_DESC;
61 // On Windows, valid handles are 32 bit unsigned integers so this is safe.
62 file_desc = reinterpret_cast<intptr_t>(handle);
63 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor.
64 int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY);
65 if (posix_desc == -1) {
66 // Close the Windows HANDLE if it can't be converted.
67 CloseHandle(reinterpret_cast<HANDLE>(file_desc));
68 return -1;
69 }
70 return posix_desc;
71 #else
72 return handle;
73 #endif
74 }
75
76
56 } // namespace 77 } // namespace
57 78
58 void Plugin::ShutDownSubprocesses() { 79 void Plugin::ShutDownSubprocesses() {
59 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", 80 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n",
60 static_cast<void*>(this))); 81 static_cast<void*>(this)));
61 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", 82 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n",
62 main_subprocess_.detailed_description().c_str())); 83 main_subprocess_.detailed_description().c_str()));
63 84
64 // Shut down service runtime. This must be done before all other calls so 85 // Shut down service runtime. This must be done before all other calls so
65 // they don't block forever when waiting for the upcall thread to exit. 86 // 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
331 RequestNaClManifest(manifest_url.AsString()); 352 RequestNaClManifest(manifest_url.AsString());
332 return true; 353 return true;
333 } 354 }
334 355
335 Plugin::Plugin(PP_Instance pp_instance) 356 Plugin::Plugin(PP_Instance pp_instance)
336 : pp::Instance(pp_instance), 357 : pp::Instance(pp_instance),
337 main_subprocess_("main subprocess", NULL, NULL), 358 main_subprocess_("main subprocess", NULL, NULL),
338 uses_nonsfi_mode_(false), 359 uses_nonsfi_mode_(false),
339 wrapper_factory_(NULL), 360 wrapper_factory_(NULL),
340 time_of_last_progress_event_(0), 361 time_of_last_progress_event_(0),
341 nexe_open_time_(-1),
342 manifest_id_(-1), 362 manifest_id_(-1),
363 nexe_handle_(PP_kInvalidFileHandle),
343 nacl_interface_(NULL), 364 nacl_interface_(NULL),
344 uma_interface_(this) { 365 uma_interface_(this) {
345 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" 366 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%"
346 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); 367 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance));
347 callback_factory_.Initialize(this); 368 callback_factory_.Initialize(this);
348 nexe_downloader_.Initialize(this);
349 nacl_interface_ = GetNaClInterface(); 369 nacl_interface_ = GetNaClInterface();
350 CHECK(nacl_interface_ != NULL); 370 CHECK(nacl_interface_ != NULL);
351 371
352 // Notify PPB_NaCl_Private that the instance is created before altering any 372 // Notify PPB_NaCl_Private that the instance is created before altering any
353 // state that it tracks. 373 // state that it tracks.
354 nacl_interface_->InstanceCreated(pp_instance); 374 nacl_interface_->InstanceCreated(pp_instance);
355 // We call set_exit_status() here to ensure that the 'exitStatus' property is 375 // We call set_exit_status() here to ensure that the 'exitStatus' property is
356 // set. This can only be called when nacl_interface_ is not NULL. 376 // set. This can only be called when nacl_interface_ is not NULL.
357 set_exit_status(-1); 377 set_exit_status(-1);
358 } 378 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 436
417 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) { 437 bool Plugin::HandleDocumentLoad(const pp::URLLoader& url_loader) {
418 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n", 438 PLUGIN_PRINTF(("Plugin::HandleDocumentLoad (this=%p)\n",
419 static_cast<void*>(this))); 439 static_cast<void*>(this)));
420 // We don't know if the plugin will handle the document load, but return 440 // We don't know if the plugin will handle the document load, but return
421 // true in order to give it a chance to respond once the proxy is started. 441 // true in order to give it a chance to respond once the proxy is started.
422 return true; 442 return true;
423 } 443 }
424 444
425 void Plugin::NexeFileDidOpen(int32_t pp_error) { 445 void Plugin::NexeFileDidOpen(int32_t pp_error) {
426 NaClFileInfo tmp_info(nexe_downloader_.GetFileInfo()); 446 if (pp_error != PP_OK)
427 NaClFileInfoAutoCloser info(&tmp_info);
428
429 int64_t nexe_bytes_read = -1;
430 if (pp_error == PP_OK && info.get_desc() != NACL_NO_FILE_DESC) {
431 struct stat stat_buf;
432 if (0 == fstat(info.get_desc(), &stat_buf))
433 nexe_bytes_read = stat_buf.st_size;
434 }
435
436 int64_t now = NaClGetTimeOfDayMicroseconds();
437 int64_t download_time;
438 if (now < nexe_open_time_)
439 download_time = 0;
440 else
441 download_time = now - nexe_open_time_;
442
443 nacl_interface_->NexeFileDidOpen(
444 pp_instance(),
445 pp_error,
446 info.get_desc(),
447 nexe_downloader_.status_code(),
448 nexe_bytes_read,
449 nexe_downloader_.url().c_str(),
450 download_time / 1000);
451
452 if (nexe_bytes_read == -1)
453 return; 447 return;
454 448
449 int32_t desc = ConvertFileDescriptor(nexe_handle_);
450 nexe_handle_ = PP_kInvalidFileHandle; // Clear out nexe handle.
451
455 nacl::scoped_ptr<nacl::DescWrapper> 452 nacl::scoped_ptr<nacl::DescWrapper>
456 wrapper(wrapper_factory()->MakeFileDesc(info.Release().desc, O_RDONLY)); 453 wrapper(wrapper_factory()->MakeFileDesc(desc, O_RDONLY));
457 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); 454 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n");
458 LoadNaClModule( 455 LoadNaClModule(
459 wrapper.release(), 456 wrapper.release(),
460 uses_nonsfi_mode_, 457 uses_nonsfi_mode_,
461 true, /* enable_dyncode_syscalls */ 458 true, /* enable_dyncode_syscalls */
462 true, /* enable_exception_handling */ 459 true, /* enable_exception_handling */
463 false, /* enable_crash_throttling */ 460 false, /* enable_crash_throttling */
464 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation), 461 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation),
465 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); 462 callback_factory_.NewCallback(&Plugin::NexeDidCrash));
466 } 463 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 HistogramSizeKB("NaCl.Perf.Size.Manifest", 546 HistogramSizeKB("NaCl.Perf.Size.Manifest",
550 static_cast<int32_t>(manifest_json.length() / 1024)); 547 static_cast<int32_t>(manifest_json.length() / 1024));
551 if (!SetManifestObject(manifest_json)) 548 if (!SetManifestObject(manifest_json))
552 return; 549 return;
553 550
554 PP_Var pp_program_url; 551 PP_Var pp_program_url;
555 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; 552 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
556 PP_Bool uses_nonsfi_mode; 553 PP_Bool uses_nonsfi_mode;
557 if (nacl_interface_->GetManifestProgramURL(pp_instance(), 554 if (nacl_interface_->GetManifestProgramURL(pp_instance(),
558 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { 555 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) {
559 std::string program_url = pp::Var(pp::PASS_REF, pp_program_url).AsString(); 556 program_url_ = pp::Var(pp::PASS_REF, pp_program_url).AsString();
560 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of 557 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of
561 // this function. 558 // this function.
562 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str()); 559 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url_.c_str());
563 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); 560 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode);
564 if (pnacl_options.translate) { 561 if (pnacl_options.translate) {
565 pp::CompletionCallback translate_callback = 562 pp::CompletionCallback translate_callback =
566 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); 563 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate);
567 pnacl_coordinator_.reset( 564 pnacl_coordinator_.reset(
568 PnaclCoordinator::BitcodeToNative(this, 565 PnaclCoordinator::BitcodeToNative(this,
569 program_url, 566 program_url_,
570 pnacl_options, 567 pnacl_options,
571 translate_callback)); 568 translate_callback));
572 return; 569 return;
573 } else { 570 } else {
574 nexe_open_time_ = NaClGetTimeOfDayMicroseconds(); 571 pp::CompletionCallback open_callback =
575 // Try the fast path first. This will only block if the file is installed. 572 callback_factory_.NewCallback(&Plugin::NexeFileDidOpen);
576 if (OpenURLFast(program_url, &nexe_downloader_)) { 573 // Will always call the callback on success or failure.
577 NexeFileDidOpen(PP_OK); 574 nacl_interface_->DownloadNexe(pp_instance(),
578 } else { 575 program_url_.c_str(),
579 pp::CompletionCallback open_callback = 576 &nexe_handle_,
580 callback_factory_.NewCallback(&Plugin::NexeFileDidOpen); 577 open_callback.pp_completion_callback());
581 // Will always call the callback on success or failure.
582 CHECK(
583 nexe_downloader_.Open(program_url,
584 DOWNLOAD_TO_FILE,
585 open_callback,
586 true,
587 &UpdateDownloadProgress));
588 }
589 return; 578 return;
590 } 579 }
591 } 580 }
592 } 581 }
593 582
594 void Plugin::RequestNaClManifest(const nacl::string& url) { 583 void Plugin::RequestNaClManifest(const nacl::string& url) {
595 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); 584 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str()));
596 pp::CompletionCallback open_callback = 585 pp::CompletionCallback open_callback =
597 callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen); 586 callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen);
598 nacl_interface_->RequestNaClManifest(pp_instance(), 587 nacl_interface_->RequestNaClManifest(pp_instance(),
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 // If true, will always call the callback on success or failure. 675 // If true, will always call the callback on success or failure.
687 return downloader->Open(url, 676 return downloader->Open(url,
688 DOWNLOAD_TO_FILE, 677 DOWNLOAD_TO_FILE,
689 open_callback, 678 open_callback,
690 true, 679 true,
691 &UpdateDownloadProgress); 680 &UpdateDownloadProgress);
692 } 681 }
693 682
694 683
695 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) { 684 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) {
696 const nacl::string& url = nexe_downloader_.url();
697 nacl_interface_->ReportLoadSuccess( 685 nacl_interface_->ReportLoadSuccess(
698 pp_instance(), url.c_str(), loaded_bytes, total_bytes); 686 pp_instance(), program_url_.c_str(), loaded_bytes, total_bytes);
699 } 687 }
700 688
701 689
702 void Plugin::ReportLoadError(const ErrorInfo& error_info) { 690 void Plugin::ReportLoadError(const ErrorInfo& error_info) {
703 nacl_interface_->ReportLoadError(pp_instance(), 691 nacl_interface_->ReportLoadError(pp_instance(),
704 error_info.error_code(), 692 error_info.error_code(),
705 error_info.message().c_str(), 693 error_info.message().c_str(),
706 error_info.console_message().c_str()); 694 error_info.console_message().c_str());
707 } 695 }
708 696
(...skipping 15 matching lines...) Expand all
724 // Rate limit progress events to a maximum of 100 per second. 712 // Rate limit progress events to a maximum of 100 per second.
725 int64_t time = NaClGetTimeOfDayMicroseconds(); 713 int64_t time = NaClGetTimeOfDayMicroseconds();
726 int64_t elapsed = time - plugin->time_of_last_progress_event_; 714 int64_t elapsed = time - plugin->time_of_last_progress_event_;
727 const int64_t kTenMilliseconds = 10000; 715 const int64_t kTenMilliseconds = 10000;
728 if (elapsed > kTenMilliseconds) { 716 if (elapsed > kTenMilliseconds) {
729 plugin->time_of_last_progress_event_ = time; 717 plugin->time_of_last_progress_event_ = time;
730 718
731 // Find the URL loader that sent this notification. 719 // Find the URL loader that sent this notification.
732 const FileDownloader* file_downloader = 720 const FileDownloader* file_downloader =
733 plugin->FindFileDownloader(pp_resource); 721 plugin->FindFileDownloader(pp_resource);
734 // If not a streamed file, it must be the .nexe loader. 722 nacl::string url;
735 if (file_downloader == NULL) 723 if (file_downloader)
736 file_downloader = &plugin->nexe_downloader_; 724 url = file_downloader->url();
737 nacl::string url = file_downloader->url();
738 LengthComputable length_computable = (total_bytes_to_be_received >= 0) ? 725 LengthComputable length_computable = (total_bytes_to_be_received >= 0) ?
739 LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE; 726 LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE;
740 727
741 plugin->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, 728 plugin->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS,
742 url, 729 url,
743 length_computable, 730 length_computable,
744 bytes_received, 731 bytes_received,
745 total_bytes_to_be_received); 732 total_bytes_to_be_received);
746 } 733 }
747 } 734 }
748 } 735 }
749 736
750 const FileDownloader* Plugin::FindFileDownloader( 737 const FileDownloader* Plugin::FindFileDownloader(
751 PP_Resource url_loader) const { 738 PP_Resource url_loader) const {
752 const FileDownloader* file_downloader = NULL; 739 const FileDownloader* file_downloader = NULL;
753 if (url_loader == nexe_downloader_.url_loader()) { 740 std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin();
754 file_downloader = &nexe_downloader_; 741 while (it != url_downloaders_.end()) {
755 } else { 742 if (url_loader == (*it)->url_loader()) {
756 std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin(); 743 file_downloader = (*it);
757 while (it != url_downloaders_.end()) { 744 break;
758 if (url_loader == (*it)->url_loader()) {
759 file_downloader = (*it);
760 break;
761 }
762 ++it;
763 } 745 }
746 ++it;
764 } 747 }
765 return file_downloader; 748 return file_downloader;
766 } 749 }
767 750
768 void Plugin::ReportSelLdrLoadStatus(int status) { 751 void Plugin::ReportSelLdrLoadStatus(int status) {
769 HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status)); 752 HistogramEnumerateSelLdrLoadStatus(static_cast<NaClErrorCode>(status));
770 } 753 }
771 754
772 void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type, 755 void Plugin::EnqueueProgressEvent(PP_NaClEventType event_type,
773 const nacl::string& url, 756 const nacl::string& url,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 812
830 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, 813 void Plugin::SetExitStatusOnMainThread(int32_t pp_error,
831 int exit_status) { 814 int exit_status) {
832 DCHECK(pp::Module::Get()->core()->IsMainThread()); 815 DCHECK(pp::Module::Get()->core()->IsMainThread());
833 DCHECK(nacl_interface_); 816 DCHECK(nacl_interface_);
834 nacl_interface_->SetExitStatus(pp_instance(), exit_status); 817 nacl_interface_->SetExitStatus(pp_instance(), exit_status);
835 } 818 }
836 819
837 820
838 } // namespace plugin 821 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/plugin.h ('k') | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698