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

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

Issue 131413009: Prototype: Use Chromium IPC for plugin LOAD_MODULE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased, some FIXMEs cleaned up Created 6 years, 10 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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 // Log the status codes in rough buckets - 1XX, 2XX, etc. 279 // Log the status codes in rough buckets - 1XX, 2XX, etc.
280 int sample = status / 100; 280 int sample = status / 100;
281 // HTTP status codes only go up to 5XX, using "6" to indicate an internal 281 // HTTP status codes only go up to 5XX, using "6" to indicate an internal
282 // error. 282 // error.
283 // Note: installed files may have "0" for a status code. 283 // Note: installed files may have "0" for a status code.
284 if (status < 0 || status >= 600) 284 if (status < 0 || status >= 600)
285 sample = 6; 285 sample = 6;
286 HistogramEnumerate(name, sample, 7, 6); 286 HistogramEnumerate(name, sample, 7, 6);
287 } 287 }
288 288
289 bool Plugin::LoadNaClModuleCommon(nacl::DescWrapper* wrapper, 289 void Plugin::StartSelLdrOnMainThread(int32_t pp_error,
290 NaClSubprocess* subprocess, 290 ServiceRuntime* service_runtime,
291 const Manifest* manifest, 291 const SelLdrStartParams& params,
292 bool should_report_uma, 292 PP_CompletionCallback callback) {
293 const SelLdrStartParams& params, 293 service_runtime->StartSelLdr(params, callback);
294 const pp::CompletionCallback& init_done_cb, 294 }
295 const pp::CompletionCallback& crash_cb) { 295
296 ErrorInfo error_info; 296 void Plugin::SignalStartSelLdrDone(int32_t pp_error,
297 ServiceRuntime* new_service_runtime = 297 ServiceRuntime* service_runtime) {
298 new ServiceRuntime(this, manifest, should_report_uma, init_done_cb, 298 PLUGIN_PRINTF(("Plugin::SignalStartSelLdrDone (this=%p, pp_error=%"
299 crash_cb); 299 NACL_PRId32 ")\n", static_cast<void*>(this), pp_error));
300 subprocess->set_service_runtime(new_service_runtime); 300 start_sel_ldr_success_ = (pp_error == PP_OK);
301 service_runtime->SignalStartSelLdrDone();
302 }
303
304 bool Plugin::LoadNaClModuleFromBackgroundThread(
305 nacl::DescWrapper* wrapper,
306 NaClSubprocess* subprocess,
307 const Manifest* manifest,
308 const SelLdrStartParams& params) {
309 ServiceRuntime* service_runtime =
310 new ServiceRuntime(this, manifest, false, pp::BlockUntilComplete(),
311 pp::BlockUntilComplete());
312 subprocess->set_service_runtime(service_runtime);
301 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime=%p)\n", 313 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime=%p)\n",
302 static_cast<void*>(new_service_runtime))); 314 static_cast<void*>(service_runtime)));
303 if (should_report_uma && NULL == new_service_runtime) { 315 if (NULL == service_runtime) {
304 error_info.SetReport(
305 ERROR_SEL_LDR_INIT,
306 "sel_ldr init failure " + subprocess->description());
307 ReportLoadError(error_info);
308 return false; 316 return false;
309 } 317 }
310 318
311 // Now start the SelLdr instance. This must be created on the main thread. 319 // Now start the SelLdr instance. This must be created on the main thread.
312 pp::Core* core = pp::Module::Get()->core(); 320 pp::Core* core = pp::Module::Get()->core();
313 bool service_runtime_started; 321 pp::CompletionCallback connected_callback =
314 if (core->IsMainThread()) { 322 callback_factory_.NewCallback(&Plugin::SignalStartSelLdrDone,
315 StartSelLdrOnMainThread(PP_OK, new_service_runtime, params, 323 service_runtime);
316 &service_runtime_started); 324 pp::CompletionCallback callback = callback_factory_.NewCallback(
317 } else { 325 &Plugin::StartSelLdrOnMainThread, service_runtime, params,
318 pp::CompletionCallback callback = 326 connected_callback.pp_completion_callback());
319 callback_factory_.NewCallback(&Plugin::StartSelLdrOnMainThread, 327 core->CallOnMainThread(0, callback, 0);
320 new_service_runtime, params, 328 service_runtime->WaitForSelLdrStart();
321 &service_runtime_started); 329 if (!start_sel_ldr_success_) {
322 core->CallOnMainThread(0, callback, 0);
323 new_service_runtime->WaitForSelLdrStart();
324 }
325 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (service_runtime_started=%d)\n",
326 service_runtime_started));
327 if (!service_runtime_started) {
328 return false; 330 return false;
329 } 331 }
330 332
331 // Now actually load the nexe, which can happen on a background thread. 333 // Now actually load the nexe, which can happen on a background thread.
332 bool nexe_loaded = new_service_runtime->LoadNexeAndStart(wrapper, 334 bool nexe_loaded = service_runtime->LoadNexeAndStart(
333 crash_cb); 335 wrapper, pp::BlockUntilComplete());
334 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (nexe_loaded=%d)\n", 336 PLUGIN_PRINTF(("Plugin::LoadNaClModuleCommon (nexe_loaded=%d)\n",
335 nexe_loaded)); 337 nexe_loaded));
336 return nexe_loaded; 338 return nexe_loaded;
337 } 339 }
338 340
339 void Plugin::StartSelLdrOnMainThread(int32_t pp_error,
340 ServiceRuntime* service_runtime,
341 const SelLdrStartParams& params,
342 bool* success) {
343 if (pp_error != PP_OK) {
344 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg "
345 "-- SHOULD NOT HAPPEN\n"));
346 *success = false;
347 return;
348 }
349 *success = service_runtime->StartSelLdr(params);
350 // Signal outside of StartSelLdr here, so that the write to *success
351 // is done before signaling.
352 service_runtime->SignalStartSelLdrDone();
353 }
354
355 void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, 341 void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper,
356 bool enable_dyncode_syscalls, 342 bool enable_dyncode_syscalls,
357 bool enable_exception_handling, 343 bool enable_exception_handling,
358 bool enable_crash_throttling, 344 bool enable_crash_throttling,
359 const pp::CompletionCallback& init_done_cb, 345 const pp::CompletionCallback& init_done_cb,
360 const pp::CompletionCallback& crash_cb) { 346 const pp::CompletionCallback& crash_cb) {
347 nacl::scoped_ptr<nacl::DescWrapper> scoped_wrapper(wrapper);
348 pp::Core* core = pp::Module::Get()->core();
349 DCHECK(core->IsMainThread());
350
351 ErrorInfo error_info;
361 // Before forking a new sel_ldr process, ensure that we do not leak 352 // Before forking a new sel_ldr process, ensure that we do not leak
362 // the ServiceRuntime object for an existing subprocess, and that any 353 // the ServiceRuntime object for an existing subprocess, and that any
363 // associated listener threads do not go unjoined because if they 354 // associated listener threads do not go unjoined because if they
364 // outlive the Plugin object, they will not be memory safe. 355 // outlive the Plugin object, they will not be memory safe.
365 ShutDownSubprocesses(); 356 ShutDownSubprocesses();
366 SelLdrStartParams params(manifest_base_url(), 357 SelLdrStartParams params(manifest_base_url(),
367 true /* uses_irt */, 358 true /* uses_irt */,
368 true /* uses_ppapi */, 359 true /* uses_ppapi */,
369 enable_dev_interfaces_, 360 enable_dev_interfaces_,
370 enable_dyncode_syscalls, 361 enable_dyncode_syscalls,
371 enable_exception_handling, 362 enable_exception_handling,
372 enable_crash_throttling); 363 enable_crash_throttling);
373 if (LoadNaClModuleCommon(wrapper, &main_subprocess_, manifest_.get(), 364 ServiceRuntime* service_runtime =
374 true /* should_report_uma */, 365 new ServiceRuntime(this, manifest_.get(), true, init_done_cb, crash_cb);
375 params, init_done_cb, crash_cb)) { 366 main_subprocess_.set_service_runtime(service_runtime);
376 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", 367 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n",
377 main_subprocess_.detailed_description().c_str())); 368 static_cast<void*>(service_runtime)));
369 if (NULL == service_runtime) {
370 error_info.SetReport(
371 ERROR_SEL_LDR_INIT,
372 "sel_ldr init failure " + main_subprocess_.description());
373 ReportLoadError(error_info);
374 return;
375 }
376
377 pp::CompletionCallback callback = callback_factory_.NewCallback(
378 &Plugin::LoadNexeOnMainThread,
379 service_runtime, scoped_wrapper.release(), crash_cb);
380 StartSelLdrOnMainThread(PP_OK, service_runtime, params,
381 callback.pp_completion_callback());
382 }
383
384 void Plugin::LoadNexeOnMainThread(int32_t pp_error,
385 ServiceRuntime* service_runtime,
386 nacl::DescWrapper* wrapper,
387 const pp::CompletionCallback& crash_cb) {
388 nacl::scoped_ptr<nacl::DescWrapper> scoped_wrapper(wrapper);
389 fprintf(stderr, "Plugin::LoadNexeOnMainThread\n");
390 ErrorInfo error_info;
391 if (pp_error != PP_OK) {
392 error_info.SetReport(
393 ERROR_SEL_LDR_INIT,
394 "sel_ldr start failure " + main_subprocess_.description());
395 ReportLoadError(error_info);
396 return;
397 }
398
399 bool nexe_loaded = service_runtime->LoadNexeAndStart(wrapper, crash_cb);
400 if (nexe_loaded) {
401 PLUGIN_PRINTF(("Plugin::LoadNaClModule (nexe_loaded=%d)\n", nexe_loaded));
378 } 402 }
379 } 403 }
380 404
381 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { 405 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) {
382 if (!main_subprocess_.StartSrpcServices()) { 406 if (!main_subprocess_.StartSrpcServices()) {
383 // The NaCl process probably crashed. On Linux, a crash causes this error, 407 // The NaCl process probably crashed. On Linux, a crash causes this error,
384 // while on other platforms, the error is detected below, when we attempt to 408 // while on other platforms, the error is detected below, when we attempt to
385 // start the proxy. Report a module initialization error here, to make it 409 // start the proxy. Report a module initialization error here, to make it
386 // less confusing for developers. 410 // less confusing for developers.
387 NaClLog(LOG_ERROR, "LoadNaClModuleContinuationIntern: " 411 NaClLog(LOG_ERROR, "LoadNaClModuleContinuationIntern: "
(...skipping 24 matching lines...) Expand all
412 return false; 436 return false;
413 } 437 }
414 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", 438 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n",
415 main_subprocess_.detailed_description().c_str())); 439 main_subprocess_.detailed_description().c_str()));
416 return true; 440 return true;
417 } 441 }
418 442
419 NaClSubprocess* Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, 443 NaClSubprocess* Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper,
420 const Manifest* manifest, 444 const Manifest* manifest,
421 ErrorInfo* error_info) { 445 ErrorInfo* error_info) {
446 pp::Core* core = pp::Module::Get()->core();
447 DCHECK(!core->IsMainThread());
422 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( 448 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess(
423 new NaClSubprocess("helper module", NULL, NULL)); 449 new NaClSubprocess("helper module", NULL, NULL));
424 if (NULL == nacl_subprocess.get()) { 450 if (NULL == nacl_subprocess.get()) {
425 error_info->SetReport(ERROR_SEL_LDR_INIT, 451 error_info->SetReport(ERROR_SEL_LDR_INIT,
426 "unable to allocate helper subprocess."); 452 "unable to allocate helper subprocess.");
427 return NULL; 453 return NULL;
428 } 454 }
429 455
430 // Do not report UMA stats for translator-related nexes. 456 // Do not report UMA stats for translator-related nexes.
431 // TODO(sehr): define new UMA stats for translator related nexe events. 457 // TODO(sehr): define new UMA stats for translator related nexe events.
432 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is 458 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is
433 // done to save on address space and swap space. 459 // done to save on address space and swap space.
434 // TODO(jvoung): See if we still need the uses_ppapi variable, now that 460 // TODO(jvoung): See if we still need the uses_ppapi variable, now that
435 // LaunchSelLdr always happens on the main thread. 461 // LaunchSelLdr always happens on the main thread.
436 SelLdrStartParams params(manifest_base_url(), 462 SelLdrStartParams params(manifest_base_url(),
437 false /* uses_irt */, 463 false /* uses_irt */,
438 false /* uses_ppapi */, 464 false /* uses_ppapi */,
439 enable_dev_interfaces_, 465 enable_dev_interfaces_,
440 false /* enable_dyncode_syscalls */, 466 false /* enable_dyncode_syscalls */,
441 false /* enable_exception_handling */, 467 false /* enable_exception_handling */,
442 true /* enable_crash_throttling */); 468 true /* enable_crash_throttling */);
443 if (!LoadNaClModuleCommon(wrapper, nacl_subprocess.get(), manifest, 469 if (!LoadNaClModuleFromBackgroundThread(wrapper,
444 false /* should_report_uma */, 470 nacl_subprocess.get(),
445 params, 471 manifest,
446 pp::BlockUntilComplete(), 472 params)) {
447 pp::BlockUntilComplete())) {
448 return NULL; 473 return NULL;
449 } 474 }
450 // We need not wait for the init_done callback. We can block 475 // We need not wait for the init_done callback. We can block
451 // here in StartSrpcServices, since helper NaCl modules 476 // here in StartSrpcServices, since helper NaCl modules
452 // are spawned from a private thread. 477 // are spawned from a private thread.
453 // 478 //
454 // TODO(bsy): if helper module crashes, we should abort. 479 // TODO(bsy): if helper module crashes, we should abort.
455 // crash_cb is not used here, so we are relying on crashes 480 // crash_cb is not used here, so we are relying on crashes
456 // being detected in StartSrpcServices or later. 481 // being detected in StartSrpcServices or later.
457 // 482 //
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 nexe_downloader_.url_to_open(), 820 nexe_downloader_.url_to_open(),
796 LENGTH_IS_COMPUTABLE, 821 LENGTH_IS_COMPUTABLE,
797 nexe_bytes_read, 822 nexe_bytes_read,
798 nexe_bytes_read); 823 nexe_bytes_read);
799 824
800 load_start_ = NaClGetTimeOfDayMicroseconds(); 825 load_start_ = NaClGetTimeOfDayMicroseconds();
801 nacl::scoped_ptr<nacl::DescWrapper> 826 nacl::scoped_ptr<nacl::DescWrapper>
802 wrapper(wrapper_factory()->MakeFileDesc(file_desc_ok_to_close, O_RDONLY)); 827 wrapper(wrapper_factory()->MakeFileDesc(file_desc_ok_to_close, O_RDONLY));
803 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); 828 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n");
804 LoadNaClModule( 829 LoadNaClModule(
805 wrapper.get(), 830 wrapper.release(),
806 true, /* enable_dyncode_syscalls */ 831 true, /* enable_dyncode_syscalls */
807 true, /* enable_exception_handling */ 832 true, /* enable_exception_handling */
808 false, /* enable_crash_throttling */ 833 false, /* enable_crash_throttling */
809 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation), 834 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation),
810 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); 835 callback_factory_.NewCallback(&Plugin::NexeDidCrash));
811 } 836 }
812 837
813 void Plugin::NexeFileDidOpenContinuation(int32_t pp_error) { 838 void Plugin::NexeFileDidOpenContinuation(int32_t pp_error) {
814 ErrorInfo error_info; 839 ErrorInfo error_info;
815 bool was_successful; 840 bool was_successful;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 if (pp_error != PP_OK) { 937 if (pp_error != PP_OK) {
913 // Error should have been reported by pnacl. Just return. 938 // Error should have been reported by pnacl. Just return.
914 PLUGIN_PRINTF(("Plugin::BitcodeDidTranslate error in Pnacl\n")); 939 PLUGIN_PRINTF(("Plugin::BitcodeDidTranslate error in Pnacl\n"));
915 return; 940 return;
916 } 941 }
917 942
918 // Inform JavaScript that we successfully translated the bitcode to a nexe. 943 // Inform JavaScript that we successfully translated the bitcode to a nexe.
919 nacl::scoped_ptr<nacl::DescWrapper> 944 nacl::scoped_ptr<nacl::DescWrapper>
920 wrapper(pnacl_coordinator_.get()->ReleaseTranslatedFD()); 945 wrapper(pnacl_coordinator_.get()->ReleaseTranslatedFD());
921 LoadNaClModule( 946 LoadNaClModule(
922 wrapper.get(), 947 wrapper.release(),
923 false, /* enable_dyncode_syscalls */ 948 false, /* enable_dyncode_syscalls */
924 false, /* enable_exception_handling */ 949 false, /* enable_exception_handling */
925 true, /* enable_crash_throttling */ 950 true, /* enable_crash_throttling */
926 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslateContinuation), 951 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslateContinuation),
927 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); 952 callback_factory_.NewCallback(&Plugin::NexeDidCrash));
928 } 953 }
929 954
930 void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) { 955 void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) {
931 ErrorInfo error_info; 956 ErrorInfo error_info;
932 bool was_successful = LoadNaClModuleContinuationIntern(&error_info); 957 bool was_successful = LoadNaClModuleContinuationIntern(&error_info);
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 DCHECK(pp::Module::Get()->core()->IsMainThread()); 1596 DCHECK(pp::Module::Get()->core()->IsMainThread());
1572 DCHECK(nacl_interface_); 1597 DCHECK(nacl_interface_);
1573 exit_status_ = exit_status; 1598 exit_status_ = exit_status;
1574 nacl_interface_->SetReadOnlyProperty(pp_instance(), 1599 nacl_interface_->SetReadOnlyProperty(pp_instance(),
1575 pp::Var("exitStatus").pp_var(), 1600 pp::Var("exitStatus").pp_var(),
1576 pp::Var(exit_status_).pp_var()); 1601 pp::Var(exit_status_).pp_var());
1577 } 1602 }
1578 1603
1579 1604
1580 } // namespace plugin 1605 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698