Chromium Code Reviews| 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 #include "ppapi/native_client/src/trusted/plugin/plugin.h" | 5 #include "ppapi/native_client/src/trusted/plugin/plugin.h" |
| 6 | 6 |
| 7 #include <sys/stat.h> | 7 #include <sys/stat.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 | 34 |
| 35 namespace plugin { | 35 namespace plugin { |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 // Up to 20 seconds | 39 // Up to 20 seconds |
| 40 const int64_t kTimeSmallMin = 1; // in ms | 40 const int64_t kTimeSmallMin = 1; // in ms |
| 41 const int64_t kTimeSmallMax = 20000; // in ms | 41 const int64_t kTimeSmallMax = 20000; // in ms |
| 42 const uint32_t kTimeSmallBuckets = 100; | 42 const uint32_t kTimeSmallBuckets = 100; |
| 43 | 43 |
| 44 const PP_NaClFileInfo kInvalidNaClFileInfo = { | |
| 45 PP_kInvalidFileHandle, | |
| 46 0, // token_lo | |
| 47 0, // token_hi | |
| 48 }; | |
| 49 | |
| 50 } // namespace | 44 } // namespace |
| 51 | 45 |
| 52 void Plugin::ShutDownSubprocesses() { | 46 void Plugin::ShutDownSubprocesses() { |
| 53 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", | 47 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", |
| 54 static_cast<void*>(this))); | 48 static_cast<void*>(this))); |
| 55 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", | 49 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", |
| 56 main_subprocess_.detailed_description().c_str())); | 50 main_subprocess_.detailed_description().c_str())); |
| 57 | 51 |
| 58 // Shut down service runtime. This must be done before all other calls so | 52 // Shut down service runtime. This must be done before all other calls so |
| 59 // they don't block forever when waiting for the upcall thread to exit. | 53 // they don't block forever when waiting for the upcall thread to exit. |
| 60 main_subprocess_.Shutdown(); | 54 main_subprocess_.Shutdown(); |
| 61 | 55 |
| 62 PLUGIN_PRINTF(("Plugin::ShutDownSubprocess (this=%p, return)\n", | 56 PLUGIN_PRINTF(("Plugin::ShutDownSubprocess (this=%p, return)\n", |
| 63 static_cast<void*>(this))); | 57 static_cast<void*>(this))); |
| 64 } | 58 } |
| 65 | 59 |
| 66 void Plugin::HistogramTimeSmall(const std::string& name, | 60 void Plugin::HistogramTimeSmall(const std::string& name, |
| 67 int64_t ms) { | 61 int64_t ms) { |
| 68 if (ms < 0) return; | 62 if (ms < 0) return; |
| 69 uma_interface_.HistogramCustomTimes(name, | 63 uma_interface_.HistogramCustomTimes(name, |
| 70 ms, | 64 ms, |
| 71 kTimeSmallMin, kTimeSmallMax, | 65 kTimeSmallMin, kTimeSmallMax, |
| 72 kTimeSmallBuckets); | 66 kTimeSmallBuckets); |
| 73 } | 67 } |
| 74 | 68 |
| 75 bool Plugin::LoadHelperNaClModule(PP_FileHandle file_handle, | 69 bool Plugin::LoadHelperNaClModule(PP_NaClFileInfo file_info, |
| 76 NaClSubprocess* subprocess, | 70 NaClSubprocess* subprocess, |
| 77 const SelLdrStartParams& params) { | 71 const SelLdrStartParams& params) { |
| 78 CHECK(!pp::Module::Get()->core()->IsMainThread()); | 72 CHECK(!pp::Module::Get()->core()->IsMainThread()); |
| 79 ServiceRuntime* service_runtime = | 73 ServiceRuntime* service_runtime = |
| 80 new ServiceRuntime(this, | 74 new ServiceRuntime(this, |
| 81 false, // No main_service_runtime. | 75 false, // No main_service_runtime. |
| 82 false, // No non-SFI mode (i.e. in SFI-mode). | 76 false, // No non-SFI mode (i.e. in SFI-mode). |
| 83 pp::BlockUntilComplete(), pp::BlockUntilComplete()); | 77 pp::BlockUntilComplete(), pp::BlockUntilComplete()); |
| 84 subprocess->set_service_runtime(service_runtime); | 78 subprocess->set_service_runtime(service_runtime); |
| 85 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " | 79 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 100 if (!service_runtime->WaitForSelLdrStart()) { | 94 if (!service_runtime->WaitForSelLdrStart()) { |
| 101 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " | 95 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " |
| 102 "WaitForSelLdrStart timed out!\n")); | 96 "WaitForSelLdrStart timed out!\n")); |
| 103 return false; | 97 return false; |
| 104 } | 98 } |
| 105 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n", | 99 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n", |
| 106 service_runtime_started)); | 100 service_runtime_started)); |
| 107 if (!service_runtime_started) | 101 if (!service_runtime_started) |
| 108 return false; | 102 return false; |
| 109 | 103 |
| 110 PP_NaClFileInfo info; | |
| 111 info.handle = file_handle; | |
| 112 info.token_lo = 0; | |
| 113 info.token_hi = 0; | |
| 114 | |
| 115 // Now actually load the nexe, which can happen on a background thread. | 104 // Now actually load the nexe, which can happen on a background thread. |
| 116 // | 105 // |
| 117 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we | 106 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we |
| 118 // have to roll our own blocking logic, similar to WaitForSelLdrStart() | 107 // have to roll our own blocking logic, similar to WaitForSelLdrStart() |
| 119 // above, except without timeout logic. | 108 // above, except without timeout logic. |
| 120 pp::Module::Get()->core()->CallOnMainThread( | 109 pp::Module::Get()->core()->CallOnMainThread( |
| 121 0, | 110 0, |
| 122 callback_factory_.NewCallback( | 111 callback_factory_.NewCallback( |
| 123 &Plugin::LoadNexeAndStart, | 112 &Plugin::LoadNexeAndStart, |
| 124 service_runtime, | 113 service_runtime, |
| 125 info)); | 114 file_info)); |
| 126 return service_runtime->WaitForNexeStart(); | 115 return service_runtime->WaitForNexeStart(); |
| 127 } | 116 } |
| 128 | 117 |
| 129 void Plugin::StartSelLdrOnMainThread(int32_t pp_error, | 118 void Plugin::StartSelLdrOnMainThread(int32_t pp_error, |
| 130 ServiceRuntime* service_runtime, | 119 ServiceRuntime* service_runtime, |
| 131 const SelLdrStartParams& params, | 120 const SelLdrStartParams& params, |
| 132 pp::CompletionCallback callback) { | 121 pp::CompletionCallback callback) { |
| 133 if (pp_error != PP_OK) { | 122 if (pp_error != PP_OK) { |
| 134 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg " | 123 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg " |
| 135 "-- SHOULD NOT HAPPEN\n")); | 124 "-- SHOULD NOT HAPPEN\n")); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 | 220 |
| 232 bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance())); | 221 bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance())); |
| 233 if (result) { | 222 if (result) { |
| 234 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", | 223 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", |
| 235 main_subprocess_.detailed_description().c_str())); | 224 main_subprocess_.detailed_description().c_str())); |
| 236 } | 225 } |
| 237 return result; | 226 return result; |
| 238 } | 227 } |
| 239 | 228 |
| 240 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, | 229 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, |
| 241 PP_FileHandle file_handle, | 230 PP_NaClFileInfo file_info, |
| 242 ErrorInfo* error_info) { | 231 ErrorInfo* error_info) { |
| 243 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( | 232 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( |
| 244 new NaClSubprocess("helper module", NULL, NULL)); | 233 new NaClSubprocess("helper module", NULL, NULL)); |
| 245 if (NULL == nacl_subprocess.get()) { | 234 if (NULL == nacl_subprocess.get()) { |
| 246 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, | 235 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, |
| 247 "unable to allocate helper subprocess."); | 236 "unable to allocate helper subprocess."); |
| 248 return NULL; | 237 return NULL; |
| 249 } | 238 } |
| 250 | 239 |
| 251 // Do not report UMA stats for translator-related nexes. | 240 // Do not report UMA stats for translator-related nexes. |
| 252 // TODO(sehr): define new UMA stats for translator related nexe events. | 241 // TODO(sehr): define new UMA stats for translator related nexe events. |
| 253 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is | 242 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is |
| 254 // done to save on address space and swap space. | 243 // done to save on address space and swap space. |
| 255 // | 244 // |
| 256 // Currently, this works only in SFI-mode. So, LoadModule SRPC is still used. | 245 // Currently, this works only in SFI-mode. So, LoadModule SRPC is still used. |
| 257 // So, pass kInvalidNaClFileInfo here, and instead |file_handle| is passed | 246 // So, pass kInvalidNaClFileInfo here, and instead |file_info| is passed |
| 258 // to LoadNaClModuleFromBackgroundThread() below. | 247 // to LoadNaClModuleFromBackgroundThread() below. |
| 259 // TODO(teravest, hidehiko): Pass file_handle to params, so that LaunchSelLdr | 248 // TODO(teravest, hidehiko): Pass file_info to params, so that LaunchSelLdr |
| 260 // will look at the info. | 249 // will look at the info. |
| 250 PP_NaClFileInfo file_info_for_srpc = file_info; | |
| 251 PP_NaClFileInfo file_info_for_ipc = kInvalidNaClFileInfo; | |
|
teravest
2014/06/26 21:19:24
I don't think you need to introduce file_info_for_
jvoung (off chromium)
2014/06/26 22:48:39
Okay, will leave this as it was.
| |
| 261 SelLdrStartParams params(helper_url, | 252 SelLdrStartParams params(helper_url, |
| 262 kInvalidNaClFileInfo, | 253 file_info_for_ipc, |
| 263 false /* uses_irt */, | 254 false /* uses_irt */, |
| 264 false /* uses_ppapi */, | 255 false /* uses_ppapi */, |
| 265 false /* enable_dyncode_syscalls */, | 256 false /* enable_dyncode_syscalls */, |
| 266 false /* enable_exception_handling */, | 257 false /* enable_exception_handling */, |
| 267 true /* enable_crash_throttling */); | 258 true /* enable_crash_throttling */); |
| 268 | 259 |
| 269 // Helper NaCl modules always use the PNaCl manifest, as there is no | 260 // Helper NaCl modules always use the PNaCl manifest, as there is no |
| 270 // corresponding NMF. | 261 // corresponding NMF. |
| 271 if (!LoadHelperNaClModule(file_handle, nacl_subprocess.get(), params)) { | 262 if (!LoadHelperNaClModule(file_info_for_srpc, |
| 263 nacl_subprocess.get(), | |
| 264 params)) { | |
| 272 return NULL; | 265 return NULL; |
| 273 } | 266 } |
| 274 // We need not wait for the init_done callback. We can block | 267 // We need not wait for the init_done callback. We can block |
| 275 // here in StartSrpcServices, since helper NaCl modules | 268 // here in StartSrpcServices, since helper NaCl modules |
| 276 // are spawned from a private thread. | 269 // are spawned from a private thread. |
| 277 // | 270 // |
| 278 // TODO(bsy): if helper module crashes, we should abort. | 271 // TODO(bsy): if helper module crashes, we should abort. |
| 279 // crash_cb is not used here, so we are relying on crashes | 272 // crash_cb is not used here, so we are relying on crashes |
| 280 // being detected in StartSrpcServices or later. | 273 // being detected in StartSrpcServices or later. |
| 281 // | 274 // |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 callback_factory_.Initialize(this); | 316 callback_factory_.Initialize(this); |
| 324 nacl_interface_ = GetNaClInterface(); | 317 nacl_interface_ = GetNaClInterface(); |
| 325 CHECK(nacl_interface_ != NULL); | 318 CHECK(nacl_interface_ != NULL); |
| 326 | 319 |
| 327 // Notify PPB_NaCl_Private that the instance is created before altering any | 320 // Notify PPB_NaCl_Private that the instance is created before altering any |
| 328 // state that it tracks. | 321 // state that it tracks. |
| 329 nacl_interface_->InstanceCreated(pp_instance); | 322 nacl_interface_->InstanceCreated(pp_instance); |
| 330 // We call set_exit_status() here to ensure that the 'exitStatus' property is | 323 // We call set_exit_status() here to ensure that the 'exitStatus' property is |
| 331 // set. This can only be called when nacl_interface_ is not NULL. | 324 // set. This can only be called when nacl_interface_ is not NULL. |
| 332 set_exit_status(-1); | 325 set_exit_status(-1); |
| 333 nexe_file_info_.handle = PP_kInvalidFileHandle; | 326 nexe_file_info_ = kInvalidNaClFileInfo; |
| 334 nexe_file_info_.token_lo = 0; | |
| 335 nexe_file_info_.token_hi = 0; | |
| 336 } | 327 } |
| 337 | 328 |
| 338 | 329 |
| 339 Plugin::~Plugin() { | 330 Plugin::~Plugin() { |
| 340 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); | 331 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); |
| 341 | 332 |
| 342 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p)\n", | 333 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p)\n", |
| 343 static_cast<void*>(this))); | 334 static_cast<void*>(this))); |
| 344 // Destroy the coordinator while the rest of the data is still there | 335 // Destroy the coordinator while the rest of the data is still there |
| 345 pnacl_coordinator_.reset(NULL); | 336 pnacl_coordinator_.reset(NULL); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 | 529 |
| 539 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, | 530 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, |
| 540 int exit_status) { | 531 int exit_status) { |
| 541 DCHECK(pp::Module::Get()->core()->IsMainThread()); | 532 DCHECK(pp::Module::Get()->core()->IsMainThread()); |
| 542 DCHECK(nacl_interface_); | 533 DCHECK(nacl_interface_); |
| 543 nacl_interface_->SetExitStatus(pp_instance(), exit_status); | 534 nacl_interface_->SetExitStatus(pp_instance(), exit_status); |
| 544 } | 535 } |
| 545 | 536 |
| 546 | 537 |
| 547 } // namespace plugin | 538 } // namespace plugin |
| OLD | NEW |