| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 // Gather data to see if being installed changes load outcomes. | 86 // Gather data to see if being installed changes load outcomes. |
| 87 const char* name = nacl_interface_->GetIsInstalled(pp_instance()) ? | 87 const char* name = nacl_interface_->GetIsInstalled(pp_instance()) ? |
| 88 "NaCl.LoadStatus.SelLdr.InstalledApp" : | 88 "NaCl.LoadStatus.SelLdr.InstalledApp" : |
| 89 "NaCl.LoadStatus.SelLdr.NotInstalledApp"; | 89 "NaCl.LoadStatus.SelLdr.NotInstalledApp"; |
| 90 uma_interface_.HistogramEnumeration(name, error_code, NACL_ERROR_CODE_MAX); | 90 uma_interface_.HistogramEnumeration(name, error_code, NACL_ERROR_CODE_MAX); |
| 91 } | 91 } |
| 92 | 92 |
| 93 bool Plugin::LoadNaClModuleFromBackgroundThread( | 93 bool Plugin::LoadNaClModuleFromBackgroundThread( |
| 94 PP_FileHandle file_handle, | 94 PP_FileHandle file_handle, |
| 95 NaClSubprocess* subprocess, | 95 NaClSubprocess* subprocess, |
| 96 int32_t manifest_id, | |
| 97 const SelLdrStartParams& params) { | 96 const SelLdrStartParams& params) { |
| 98 CHECK(!pp::Module::Get()->core()->IsMainThread()); | 97 CHECK(!pp::Module::Get()->core()->IsMainThread()); |
| 99 ServiceRuntime* service_runtime = | 98 ServiceRuntime* service_runtime = |
| 100 new ServiceRuntime(this, manifest_id, false, uses_nonsfi_mode_, | 99 new ServiceRuntime(this, false, uses_nonsfi_mode_, |
| 101 pp::BlockUntilComplete(), pp::BlockUntilComplete()); | 100 pp::BlockUntilComplete(), pp::BlockUntilComplete()); |
| 102 subprocess->set_service_runtime(service_runtime); | 101 subprocess->set_service_runtime(service_runtime); |
| 103 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " | 102 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " |
| 104 "(service_runtime=%p)\n", | 103 "(service_runtime=%p)\n", |
| 105 static_cast<void*>(service_runtime))); | 104 static_cast<void*>(service_runtime))); |
| 106 | 105 |
| 107 // Now start the SelLdr instance. This must be created on the main thread. | 106 // Now start the SelLdr instance. This must be created on the main thread. |
| 108 bool service_runtime_started = false; | 107 bool service_runtime_started = false; |
| 109 pp::CompletionCallback sel_ldr_callback = | 108 pp::CompletionCallback sel_ldr_callback = |
| 110 callback_factory_.NewCallback(&Plugin::SignalStartSelLdrDone, | 109 callback_factory_.NewCallback(&Plugin::SignalStartSelLdrDone, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 SelLdrStartParams params(manifest_base_url_str, | 180 SelLdrStartParams params(manifest_base_url_str, |
| 182 true /* uses_irt */, | 181 true /* uses_irt */, |
| 183 true /* uses_ppapi */, | 182 true /* uses_ppapi */, |
| 184 uses_nonsfi_mode, | 183 uses_nonsfi_mode, |
| 185 enable_dev_interfaces, | 184 enable_dev_interfaces, |
| 186 enable_dyncode_syscalls, | 185 enable_dyncode_syscalls, |
| 187 enable_exception_handling, | 186 enable_exception_handling, |
| 188 enable_crash_throttling); | 187 enable_crash_throttling); |
| 189 ErrorInfo error_info; | 188 ErrorInfo error_info; |
| 190 ServiceRuntime* service_runtime = | 189 ServiceRuntime* service_runtime = |
| 191 new ServiceRuntime(this, manifest_id_, true, uses_nonsfi_mode, | 190 new ServiceRuntime(this, true, uses_nonsfi_mode, |
| 192 init_done_cb, crash_cb); | 191 init_done_cb, crash_cb); |
| 193 main_subprocess_.set_service_runtime(service_runtime); | 192 main_subprocess_.set_service_runtime(service_runtime); |
| 194 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", | 193 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", |
| 195 static_cast<void*>(service_runtime))); | 194 static_cast<void*>(service_runtime))); |
| 196 if (NULL == service_runtime) { | 195 if (NULL == service_runtime) { |
| 197 error_info.SetReport( | 196 error_info.SetReport( |
| 198 PP_NACL_ERROR_SEL_LDR_INIT, | 197 PP_NACL_ERROR_SEL_LDR_INIT, |
| 199 "sel_ldr init failure " + main_subprocess_.description()); | 198 "sel_ldr init failure " + main_subprocess_.description()); |
| 200 ReportLoadError(error_info); | 199 ReportLoadError(error_info); |
| 201 return; | 200 return; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 false /* uses_irt */, | 272 false /* uses_irt */, |
| 274 false /* uses_ppapi */, | 273 false /* uses_ppapi */, |
| 275 false /* uses_nonsfi_mode */, | 274 false /* uses_nonsfi_mode */, |
| 276 enable_dev_interfaces, | 275 enable_dev_interfaces, |
| 277 false /* enable_dyncode_syscalls */, | 276 false /* enable_dyncode_syscalls */, |
| 278 false /* enable_exception_handling */, | 277 false /* enable_exception_handling */, |
| 279 true /* enable_crash_throttling */); | 278 true /* enable_crash_throttling */); |
| 280 | 279 |
| 281 // Helper NaCl modules always use the PNaCl manifest, as there is no | 280 // Helper NaCl modules always use the PNaCl manifest, as there is no |
| 282 // corresponding NMF. | 281 // corresponding NMF. |
| 283 int32_t manifest_id = nacl_interface_->CreatePnaclManifest(pp_instance()); | |
| 284 if (!LoadNaClModuleFromBackgroundThread(file_handle, nacl_subprocess.get(), | 282 if (!LoadNaClModuleFromBackgroundThread(file_handle, nacl_subprocess.get(), |
| 285 manifest_id, params)) { | 283 params)) { |
| 286 return NULL; | 284 return NULL; |
| 287 } | 285 } |
| 288 // We need not wait for the init_done callback. We can block | 286 // We need not wait for the init_done callback. We can block |
| 289 // here in StartSrpcServices, since helper NaCl modules | 287 // here in StartSrpcServices, since helper NaCl modules |
| 290 // are spawned from a private thread. | 288 // are spawned from a private thread. |
| 291 // | 289 // |
| 292 // TODO(bsy): if helper module crashes, we should abort. | 290 // TODO(bsy): if helper module crashes, we should abort. |
| 293 // crash_cb is not used here, so we are relying on crashes | 291 // crash_cb is not used here, so we are relying on crashes |
| 294 // being detected in StartSrpcServices or later. | 292 // being detected in StartSrpcServices or later. |
| 295 // | 293 // |
| (...skipping 28 matching lines...) Expand all Loading... |
| 324 RequestNaClManifest(manifest_url.AsString()); | 322 RequestNaClManifest(manifest_url.AsString()); |
| 325 return true; | 323 return true; |
| 326 } | 324 } |
| 327 | 325 |
| 328 Plugin::Plugin(PP_Instance pp_instance) | 326 Plugin::Plugin(PP_Instance pp_instance) |
| 329 : pp::Instance(pp_instance), | 327 : pp::Instance(pp_instance), |
| 330 main_subprocess_("main subprocess", NULL, NULL), | 328 main_subprocess_("main subprocess", NULL, NULL), |
| 331 uses_nonsfi_mode_(false), | 329 uses_nonsfi_mode_(false), |
| 332 wrapper_factory_(NULL), | 330 wrapper_factory_(NULL), |
| 333 time_of_last_progress_event_(0), | 331 time_of_last_progress_event_(0), |
| 334 manifest_id_(-1), | |
| 335 nacl_interface_(NULL), | 332 nacl_interface_(NULL), |
| 336 uma_interface_(this) { | 333 uma_interface_(this) { |
| 337 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" | 334 PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" |
| 338 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); | 335 NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); |
| 339 callback_factory_.Initialize(this); | 336 callback_factory_.Initialize(this); |
| 340 nacl_interface_ = GetNaClInterface(); | 337 nacl_interface_ = GetNaClInterface(); |
| 341 CHECK(nacl_interface_ != NULL); | 338 CHECK(nacl_interface_ != NULL); |
| 342 | 339 |
| 343 // Notify PPB_NaCl_Private that the instance is created before altering any | 340 // Notify PPB_NaCl_Private that the instance is created before altering any |
| 344 // state that it tracks. | 341 // state that it tracks. |
| 345 nacl_interface_->InstanceCreated(pp_instance); | 342 nacl_interface_->InstanceCreated(pp_instance); |
| 346 // We call set_exit_status() here to ensure that the 'exitStatus' property is | 343 // We call set_exit_status() here to ensure that the 'exitStatus' property is |
| 347 // set. This can only be called when nacl_interface_ is not NULL. | 344 // set. This can only be called when nacl_interface_ is not NULL. |
| 348 set_exit_status(-1); | 345 set_exit_status(-1); |
| 349 nexe_file_info_.handle = PP_kInvalidFileHandle; | 346 nexe_file_info_.handle = PP_kInvalidFileHandle; |
| 350 nexe_file_info_.token_lo = 0; | 347 nexe_file_info_.token_lo = 0; |
| 351 nexe_file_info_.token_hi = 0; | 348 nexe_file_info_.token_hi = 0; |
| 352 } | 349 } |
| 353 | 350 |
| 354 | 351 |
| 355 Plugin::~Plugin() { | 352 Plugin::~Plugin() { |
| 356 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); | 353 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); |
| 357 | 354 |
| 358 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p)\n", | 355 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p)\n", |
| 359 static_cast<void*>(this))); | 356 static_cast<void*>(this))); |
| 360 // Destroy the coordinator while the rest of the data is still there | 357 // Destroy the coordinator while the rest of the data is still there |
| 361 pnacl_coordinator_.reset(NULL); | 358 pnacl_coordinator_.reset(NULL); |
| 362 | 359 |
| 363 // Clean up accounting for our instance inside the NaCl interface. | |
| 364 if (manifest_id_ != -1) | |
| 365 nacl_interface_->DestroyManifest(pp_instance(), manifest_id_); | |
| 366 nacl_interface_->InstanceDestroyed(pp_instance()); | 360 nacl_interface_->InstanceDestroyed(pp_instance()); |
| 367 | 361 |
| 368 // ShutDownSubprocesses shuts down the main subprocess, which shuts | 362 // ShutDownSubprocesses shuts down the main subprocess, which shuts |
| 369 // down the main ServiceRuntime object, which kills the subprocess. | 363 // down the main ServiceRuntime object, which kills the subprocess. |
| 370 // As a side effect of the subprocess being killed, the reverse | 364 // As a side effect of the subprocess being killed, the reverse |
| 371 // services thread(s) will get EOF on the reverse channel(s), and | 365 // services thread(s) will get EOF on the reverse channel(s), and |
| 372 // the thread(s) will exit. In ServiceRuntime::Shutdown, we invoke | 366 // the thread(s) will exit. In ServiceRuntime::Shutdown, we invoke |
| 373 // ReverseService::WaitForServiceThreadsToExit(), so that there will | 367 // ReverseService::WaitForServiceThreadsToExit(), so that there will |
| 374 // not be an extent thread(s) hanging around. This means that the | 368 // not be an extent thread(s) hanging around. This means that the |
| 375 // ~Plugin will block until this happens. This is a requirement, | 369 // ~Plugin will block until this happens. This is a requirement, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 int64_t loaded; | 486 int64_t loaded; |
| 493 int64_t total; | 487 int64_t total; |
| 494 pnacl_coordinator_->GetCurrentProgress(&loaded, &total); | 488 pnacl_coordinator_->GetCurrentProgress(&loaded, &total); |
| 495 ReportLoadSuccess(loaded, total); | 489 ReportLoadSuccess(loaded, total); |
| 496 } | 490 } |
| 497 } | 491 } |
| 498 | 492 |
| 499 void Plugin::NaClManifestFileDidOpen(int32_t pp_error) { | 493 void Plugin::NaClManifestFileDidOpen(int32_t pp_error) { |
| 500 PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (pp_error=%" | 494 PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (pp_error=%" |
| 501 NACL_PRId32 ")\n", pp_error)); | 495 NACL_PRId32 ")\n", pp_error)); |
| 502 if (pp_error != PP_OK || manifest_id_ == -1) | 496 if (pp_error != PP_OK) |
| 503 return; | 497 return; |
| 504 | 498 |
| 505 PP_Var pp_program_url; | 499 PP_Var pp_program_url; |
| 506 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; | 500 PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; |
| 507 PP_Bool uses_nonsfi_mode; | 501 PP_Bool uses_nonsfi_mode; |
| 508 if (nacl_interface_->GetManifestProgramURL(pp_instance(), | 502 if (nacl_interface_->GetManifestProgramURL( |
| 509 manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { | 503 pp_instance(), &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { |
| 510 program_url_ = pp::Var(pp::PASS_REF, pp_program_url).AsString(); | 504 program_url_ = pp::Var(pp::PASS_REF, pp_program_url).AsString(); |
| 511 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of | 505 // TODO(teravest): Make ProcessNaClManifest take responsibility for more of |
| 512 // this function. | 506 // this function. |
| 513 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url_.c_str()); | 507 nacl_interface_->ProcessNaClManifest(pp_instance(), program_url_.c_str()); |
| 514 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); | 508 uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); |
| 515 if (pnacl_options.translate) { | 509 if (pnacl_options.translate) { |
| 516 pp::CompletionCallback translate_callback = | 510 pp::CompletionCallback translate_callback = |
| 517 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); | 511 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); |
| 518 pnacl_coordinator_.reset( | 512 pnacl_coordinator_.reset( |
| 519 PnaclCoordinator::BitcodeToNative(this, | 513 PnaclCoordinator::BitcodeToNative(this, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 533 } | 527 } |
| 534 } | 528 } |
| 535 } | 529 } |
| 536 | 530 |
| 537 void Plugin::RequestNaClManifest(const nacl::string& url) { | 531 void Plugin::RequestNaClManifest(const nacl::string& url) { |
| 538 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); | 532 PLUGIN_PRINTF(("Plugin::RequestNaClManifest (url='%s')\n", url.c_str())); |
| 539 pp::CompletionCallback open_callback = | 533 pp::CompletionCallback open_callback = |
| 540 callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen); | 534 callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen); |
| 541 nacl_interface_->RequestNaClManifest(pp_instance(), | 535 nacl_interface_->RequestNaClManifest(pp_instance(), |
| 542 url.c_str(), | 536 url.c_str(), |
| 543 &manifest_id_, | |
| 544 open_callback.pp_completion_callback()); | 537 open_callback.pp_completion_callback()); |
| 545 } | 538 } |
| 546 | 539 |
| 547 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) { | 540 void Plugin::ReportLoadSuccess(uint64_t loaded_bytes, uint64_t total_bytes) { |
| 548 nacl_interface_->ReportLoadSuccess( | 541 nacl_interface_->ReportLoadSuccess( |
| 549 pp_instance(), program_url_.c_str(), loaded_bytes, total_bytes); | 542 pp_instance(), program_url_.c_str(), loaded_bytes, total_bytes); |
| 550 } | 543 } |
| 551 | 544 |
| 552 | 545 |
| 553 void Plugin::ReportLoadError(const ErrorInfo& error_info) { | 546 void Plugin::ReportLoadError(const ErrorInfo& error_info) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 | 602 |
| 610 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, | 603 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, |
| 611 int exit_status) { | 604 int exit_status) { |
| 612 DCHECK(pp::Module::Get()->core()->IsMainThread()); | 605 DCHECK(pp::Module::Get()->core()->IsMainThread()); |
| 613 DCHECK(nacl_interface_); | 606 DCHECK(nacl_interface_); |
| 614 nacl_interface_->SetExitStatus(pp_instance(), exit_status); | 607 nacl_interface_->SetExitStatus(pp_instance(), exit_status); |
| 615 } | 608 } |
| 616 | 609 |
| 617 | 610 |
| 618 } // namespace plugin | 611 } // namespace plugin |
| OLD | NEW |