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 |