OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #define NACL_LOG_MODULE_NAME "Plugin::ServiceRuntime" | 7 #define NACL_LOG_MODULE_NAME "Plugin::ServiceRuntime" |
8 | 8 |
9 #include "native_client/src/trusted/plugin/service_runtime.h" | 9 #include "native_client/src/trusted/plugin/service_runtime.h" |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | 53 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
54 #include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h" | 54 #include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h" |
55 | 55 |
56 #include "ppapi/c/pp_errors.h" | 56 #include "ppapi/c/pp_errors.h" |
57 #include "ppapi/c/trusted/ppb_file_io_trusted.h" | 57 #include "ppapi/c/trusted/ppb_file_io_trusted.h" |
58 #include "ppapi/cpp/core.h" | 58 #include "ppapi/cpp/core.h" |
59 #include "ppapi/cpp/completion_callback.h" | 59 #include "ppapi/cpp/completion_callback.h" |
60 #include "ppapi/cpp/file_io.h" | 60 #include "ppapi/cpp/file_io.h" |
61 | 61 |
| 62 namespace { |
| 63 |
| 64 // For doing crude quota enforcement on writes to temp files. |
| 65 // We do not allow a temp file bigger than 512 MB for now. |
| 66 const uint64_t kMaxTempQuota = 0x20000000; |
| 67 |
| 68 } // namespace |
| 69 |
62 namespace plugin { | 70 namespace plugin { |
63 | 71 |
64 PluginReverseInterface::PluginReverseInterface( | 72 PluginReverseInterface::PluginReverseInterface( |
65 nacl::WeakRefAnchor* anchor, | 73 nacl::WeakRefAnchor* anchor, |
66 Plugin* plugin, | 74 Plugin* plugin, |
67 const Manifest* manifest, | 75 const Manifest* manifest, |
68 ServiceRuntime* service_runtime, | 76 ServiceRuntime* service_runtime, |
69 pp::CompletionCallback init_done_cb, | 77 pp::CompletionCallback init_done_cb, |
70 pp::CompletionCallback crash_cb) | 78 pp::CompletionCallback crash_cb) |
71 : anchor_(anchor), | 79 : anchor_(anchor), |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 void PluginReverseInterface::ReportExitStatus(int exit_status) { | 434 void PluginReverseInterface::ReportExitStatus(int exit_status) { |
427 service_runtime_->set_exit_status(exit_status); | 435 service_runtime_->set_exit_status(exit_status); |
428 } | 436 } |
429 | 437 |
430 void PluginReverseInterface::QuotaRequest_MainThreadContinuation( | 438 void PluginReverseInterface::QuotaRequest_MainThreadContinuation( |
431 QuotaRequest* request, | 439 QuotaRequest* request, |
432 int32_t err) { | 440 int32_t err) { |
433 if (err != PP_OK) { | 441 if (err != PP_OK) { |
434 return; | 442 return; |
435 } | 443 } |
436 const PPB_FileIOTrusted* file_io_trusted = | 444 |
437 static_cast<const PPB_FileIOTrusted*>( | 445 switch (request->data.type) { |
438 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); | 446 case plugin::PepperQuotaType: { |
439 // Copy the request object because this one will be deleted on return. | 447 const PPB_FileIOTrusted* file_io_trusted = |
440 QuotaRequest* cont_for_response = new QuotaRequest(*request); // copy ctor! | 448 static_cast<const PPB_FileIOTrusted*>( |
441 pp::CompletionCallback quota_cc = WeakRefNewCallback( | 449 pp::Module::Get()->GetBrowserInterface( |
442 anchor_, | 450 PPB_FILEIOTRUSTED_INTERFACE)); |
443 this, | 451 // Copy the request object because this one will be deleted on return. |
444 &PluginReverseInterface::QuotaRequest_MainThreadResponse, | 452 // copy ctor! |
445 cont_for_response); | 453 QuotaRequest* cont_for_response = new QuotaRequest(*request); |
446 file_io_trusted->WillWrite(request->resource, | 454 pp::CompletionCallback quota_cc = WeakRefNewCallback( |
447 request->offset, | 455 anchor_, |
448 // TODO(sehr): remove need for cast. | 456 this, |
449 // Unify WillWrite interface vs Quota request. | 457 &PluginReverseInterface::QuotaRequest_MainThreadResponse, |
450 nacl::assert_cast<int32_t>( | 458 cont_for_response); |
451 request->bytes_requested), | 459 file_io_trusted->WillWrite(request->data.resource, |
452 quota_cc.pp_completion_callback()); | 460 request->offset, |
| 461 // TODO(sehr): remove need for cast. |
| 462 // Unify WillWrite interface vs Quota request. |
| 463 nacl::assert_cast<int32_t>( |
| 464 request->bytes_requested), |
| 465 quota_cc.pp_completion_callback()); |
| 466 break; |
| 467 } |
| 468 case plugin::TempQuotaType: { |
| 469 uint64_t len = request->offset + request->bytes_requested; |
| 470 nacl::MutexLocker take(&mu_); |
| 471 // Do some crude quota enforcement. |
| 472 if (len > kMaxTempQuota) { |
| 473 *request->bytes_granted = 0; |
| 474 } else { |
| 475 *request->bytes_granted = request->bytes_requested; |
| 476 } |
| 477 *request->op_complete_ptr = true; |
| 478 NaClXCondVarBroadcast(&cv_); |
| 479 break; |
| 480 } |
| 481 } |
453 // request automatically deleted | 482 // request automatically deleted |
454 } | 483 } |
455 | 484 |
456 void PluginReverseInterface::QuotaRequest_MainThreadResponse( | 485 void PluginReverseInterface::QuotaRequest_MainThreadResponse( |
457 QuotaRequest* request, | 486 QuotaRequest* request, |
458 int32_t err) { | 487 int32_t err) { |
459 NaClLog(4, | 488 NaClLog(4, |
460 "PluginReverseInterface::QuotaRequest_MainThreadResponse:" | 489 "PluginReverseInterface::QuotaRequest_MainThreadResponse:" |
461 " (resource=%"NACL_PRIx32", offset=%"NACL_PRId64", requested=%" | 490 " (resource=%"NACL_PRIx32", offset=%"NACL_PRId64", requested=%" |
462 NACL_PRId64", err=%"NACL_PRId32")\n", | 491 NACL_PRId64", err=%"NACL_PRId32")\n", |
463 request->resource, request->offset, request->bytes_requested, err); | 492 request->data.resource, |
| 493 request->offset, request->bytes_requested, err); |
464 nacl::MutexLocker take(&mu_); | 494 nacl::MutexLocker take(&mu_); |
465 if (err >= PP_OK) { | 495 if (err >= PP_OK) { |
466 *request->bytes_granted = err; | 496 *request->bytes_granted = err; |
467 } else { | 497 } else { |
468 *request->bytes_granted = 0; | 498 *request->bytes_granted = 0; |
469 } | 499 } |
470 *request->op_complete_ptr = true; | 500 *request->op_complete_ptr = true; |
471 NaClXCondVarBroadcast(&cv_); | 501 NaClXCondVarBroadcast(&cv_); |
472 // request automatically deleted | 502 // request automatically deleted |
473 } | 503 } |
474 | 504 |
475 int64_t PluginReverseInterface::RequestQuotaForWrite( | 505 int64_t PluginReverseInterface::RequestQuotaForWrite( |
476 nacl::string file_id, int64_t offset, int64_t bytes_to_write) { | 506 nacl::string file_id, int64_t offset, int64_t bytes_to_write) { |
477 NaClLog(4, | 507 NaClLog(4, |
478 "PluginReverseInterface::RequestQuotaForWrite:" | 508 "PluginReverseInterface::RequestQuotaForWrite:" |
479 " (file_id='%s', offset=%"NACL_PRId64", bytes_to_write=%" | 509 " (file_id='%s', offset=%"NACL_PRId64", bytes_to_write=%" |
480 NACL_PRId64")\n", file_id.c_str(), offset, bytes_to_write); | 510 NACL_PRId64")\n", file_id.c_str(), offset, bytes_to_write); |
481 PP_Resource resource; | 511 QuotaData quota_data; |
482 { | 512 { |
483 nacl::MutexLocker take(&mu_); | 513 nacl::MutexLocker take(&mu_); |
484 uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); | 514 uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); |
485 if (quota_map_.find(file_key) == quota_map_.end()) { | 515 if (quota_map_.find(file_key) == quota_map_.end()) { |
486 // Look up failed to find the requested quota managed resource. | 516 // Look up failed to find the requested quota managed resource. |
487 NaClLog(4, "PluginReverseInterface::RequestQuotaForWrite: failed...\n"); | 517 NaClLog(4, "PluginReverseInterface::RequestQuotaForWrite: failed...\n"); |
488 return 0; | 518 return 0; |
489 } | 519 } |
490 resource = quota_map_[file_key]; | 520 quota_data = quota_map_[file_key]; |
491 } | 521 } |
492 // Variables set by requesting quota. | 522 // Variables set by requesting quota. |
493 int64_t quota_granted = 0; | 523 int64_t quota_granted = 0; |
494 bool op_complete = false; | 524 bool op_complete = false; |
495 QuotaRequest* continuation = | 525 QuotaRequest* continuation = |
496 new QuotaRequest(resource, offset, bytes_to_write, "a_granted, | 526 new QuotaRequest(quota_data, offset, bytes_to_write, "a_granted, |
497 &op_complete); | 527 &op_complete); |
498 // The reverse service is running on a background thread and the PPAPI quota | 528 // The reverse service is running on a background thread and the PPAPI quota |
499 // methods must be invoked only from the main thread. | 529 // methods must be invoked only from the main thread. |
500 plugin::WeakRefCallOnMainThread( | 530 plugin::WeakRefCallOnMainThread( |
501 anchor_, | 531 anchor_, |
502 0, /* delay in ms */ | 532 0, /* delay in ms */ |
503 ALLOW_THIS_IN_INITIALIZER_LIST(this), | 533 ALLOW_THIS_IN_INITIALIZER_LIST(this), |
504 &plugin::PluginReverseInterface::QuotaRequest_MainThreadContinuation, | 534 &plugin::PluginReverseInterface::QuotaRequest_MainThreadContinuation, |
505 continuation); | 535 continuation); |
506 // Wait for the main thread to request quota and signal completion. | 536 // Wait for the main thread to request quota and signal completion. |
(...skipping 15 matching lines...) Expand all Loading... |
522 | 552 |
523 void PluginReverseInterface::AddQuotaManagedFile(const nacl::string& file_id, | 553 void PluginReverseInterface::AddQuotaManagedFile(const nacl::string& file_id, |
524 const pp::FileIO& file_io) { | 554 const pp::FileIO& file_io) { |
525 PP_Resource resource = file_io.pp_resource(); | 555 PP_Resource resource = file_io.pp_resource(); |
526 NaClLog(4, | 556 NaClLog(4, |
527 "PluginReverseInterface::AddQuotaManagedFile: " | 557 "PluginReverseInterface::AddQuotaManagedFile: " |
528 "(file_id='%s', file_io_ref=%"NACL_PRIx32")\n", | 558 "(file_id='%s', file_io_ref=%"NACL_PRIx32")\n", |
529 file_id.c_str(), resource); | 559 file_id.c_str(), resource); |
530 nacl::MutexLocker take(&mu_); | 560 nacl::MutexLocker take(&mu_); |
531 uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); | 561 uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); |
532 quota_map_[file_key] = resource; | 562 QuotaData data(plugin::PepperQuotaType, resource); |
| 563 quota_map_[file_key] = data; |
| 564 } |
| 565 |
| 566 void PluginReverseInterface::AddTempQuotaManagedFile( |
| 567 const nacl::string& file_id) { |
| 568 PLUGIN_PRINTF(("PluginReverseInterface::AddTempQuotaManagedFile: " |
| 569 "(file_id='%s')\n", file_id.c_str())); |
| 570 nacl::MutexLocker take(&mu_); |
| 571 uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); |
| 572 QuotaData data(plugin::TempQuotaType, 0); |
| 573 quota_map_[file_key] = data; |
533 } | 574 } |
534 | 575 |
535 ServiceRuntime::ServiceRuntime(Plugin* plugin, | 576 ServiceRuntime::ServiceRuntime(Plugin* plugin, |
536 const Manifest* manifest, | 577 const Manifest* manifest, |
537 bool should_report_uma, | 578 bool should_report_uma, |
538 pp::CompletionCallback init_done_cb, | 579 pp::CompletionCallback init_done_cb, |
539 pp::CompletionCallback crash_cb) | 580 pp::CompletionCallback crash_cb) |
540 : plugin_(plugin), | 581 : plugin_(plugin), |
541 should_report_uma_(should_report_uma), | 582 should_report_uma_(should_report_uma), |
542 reverse_service_(NULL), | 583 reverse_service_(NULL), |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 | 803 |
763 nacl::string ServiceRuntime::GetCrashLogOutput() { | 804 nacl::string ServiceRuntime::GetCrashLogOutput() { |
764 if (NULL != subprocess_.get()) { | 805 if (NULL != subprocess_.get()) { |
765 return subprocess_->GetCrashLogOutput(); | 806 return subprocess_->GetCrashLogOutput(); |
766 } else { | 807 } else { |
767 return ""; | 808 return ""; |
768 } | 809 } |
769 } | 810 } |
770 | 811 |
771 } // namespace plugin | 812 } // namespace plugin |
OLD | NEW |