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 pp_instance(), | 75 pp_instance(), |
82 false, // No main_service_runtime. | 76 false, // No main_service_runtime. |
83 false, // No non-SFI mode (i.e. in SFI-mode). | 77 false, // No non-SFI mode (i.e. in SFI-mode). |
84 pp::BlockUntilComplete(), pp::BlockUntilComplete()); | 78 pp::BlockUntilComplete(), pp::BlockUntilComplete()); |
85 subprocess->set_service_runtime(service_runtime); | 79 subprocess->set_service_runtime(service_runtime); |
(...skipping 15 matching lines...) Expand all Loading... |
101 if (!service_runtime->WaitForSelLdrStart()) { | 95 if (!service_runtime->WaitForSelLdrStart()) { |
102 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " | 96 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " |
103 "WaitForSelLdrStart timed out!\n")); | 97 "WaitForSelLdrStart timed out!\n")); |
104 return false; | 98 return false; |
105 } | 99 } |
106 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n", | 100 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n", |
107 service_runtime_started)); | 101 service_runtime_started)); |
108 if (!service_runtime_started) | 102 if (!service_runtime_started) |
109 return false; | 103 return false; |
110 | 104 |
111 PP_NaClFileInfo info; | |
112 info.handle = file_handle; | |
113 info.token_lo = 0; | |
114 info.token_hi = 0; | |
115 | |
116 // Now actually load the nexe, which can happen on a background thread. | 105 // Now actually load the nexe, which can happen on a background thread. |
117 // | 106 // |
118 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we | 107 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we |
119 // have to roll our own blocking logic, similar to WaitForSelLdrStart() | 108 // have to roll our own blocking logic, similar to WaitForSelLdrStart() |
120 // above, except without timeout logic. | 109 // above, except without timeout logic. |
121 pp::Module::Get()->core()->CallOnMainThread( | 110 pp::Module::Get()->core()->CallOnMainThread( |
122 0, | 111 0, |
123 callback_factory_.NewCallback( | 112 callback_factory_.NewCallback( |
124 &Plugin::LoadNexeAndStart, | 113 &Plugin::LoadNexeAndStart, |
125 service_runtime, | 114 service_runtime, |
126 info)); | 115 file_info)); |
127 return service_runtime->WaitForNexeStart(); | 116 return service_runtime->WaitForNexeStart(); |
128 } | 117 } |
129 | 118 |
130 void Plugin::StartSelLdrOnMainThread(int32_t pp_error, | 119 void Plugin::StartSelLdrOnMainThread(int32_t pp_error, |
131 ServiceRuntime* service_runtime, | 120 ServiceRuntime* service_runtime, |
132 const SelLdrStartParams& params, | 121 const SelLdrStartParams& params, |
133 pp::CompletionCallback callback) { | 122 pp::CompletionCallback callback) { |
134 if (pp_error != PP_OK) { | 123 if (pp_error != PP_OK) { |
135 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg " | 124 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg " |
136 "-- SHOULD NOT HAPPEN\n")); | 125 "-- SHOULD NOT HAPPEN\n")); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 221 |
233 bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance())); | 222 bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance())); |
234 if (result) { | 223 if (result) { |
235 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", | 224 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", |
236 main_subprocess_.detailed_description().c_str())); | 225 main_subprocess_.detailed_description().c_str())); |
237 } | 226 } |
238 return result; | 227 return result; |
239 } | 228 } |
240 | 229 |
241 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, | 230 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, |
242 PP_FileHandle file_handle, | 231 PP_NaClFileInfo file_info, |
243 ErrorInfo* error_info) { | 232 ErrorInfo* error_info) { |
244 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( | 233 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( |
245 new NaClSubprocess("helper module", NULL, NULL)); | 234 new NaClSubprocess("helper module", NULL, NULL)); |
246 if (NULL == nacl_subprocess.get()) { | 235 if (NULL == nacl_subprocess.get()) { |
247 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, | 236 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, |
248 "unable to allocate helper subprocess."); | 237 "unable to allocate helper subprocess."); |
249 return NULL; | 238 return NULL; |
250 } | 239 } |
251 | 240 |
252 // Do not report UMA stats for translator-related nexes. | 241 // Do not report UMA stats for translator-related nexes. |
253 // TODO(sehr): define new UMA stats for translator related nexe events. | 242 // TODO(sehr): define new UMA stats for translator related nexe events. |
254 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is | 243 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is |
255 // done to save on address space and swap space. | 244 // done to save on address space and swap space. |
256 // | 245 // |
257 // Currently, this works only in SFI-mode. So, LoadModule SRPC is still used. | 246 // Currently, this works only in SFI-mode. So, LoadModule SRPC is still used. |
258 // So, pass kInvalidNaClFileInfo here, and instead |file_handle| is passed | 247 // So, pass kInvalidNaClFileInfo here, and instead |file_info| is passed |
259 // to LoadNaClModuleFromBackgroundThread() below. | 248 // to LoadNaClModuleFromBackgroundThread() below. |
260 // TODO(teravest, hidehiko): Pass file_handle to params, so that LaunchSelLdr | 249 // TODO(teravest, hidehiko): Pass file_info to params, so that LaunchSelLdr |
261 // will look at the info. | 250 // will look at the info. |
262 SelLdrStartParams params(helper_url, | 251 SelLdrStartParams params(helper_url, |
263 kInvalidNaClFileInfo, | 252 kInvalidNaClFileInfo, |
264 false /* uses_irt */, | 253 false /* uses_irt */, |
265 false /* uses_ppapi */, | 254 false /* uses_ppapi */, |
266 false /* enable_dyncode_syscalls */, | 255 false /* enable_dyncode_syscalls */, |
267 false /* enable_exception_handling */, | 256 false /* enable_exception_handling */, |
268 true /* enable_crash_throttling */); | 257 true /* enable_crash_throttling */); |
269 | 258 |
270 // Helper NaCl modules always use the PNaCl manifest, as there is no | 259 // Helper NaCl modules always use the PNaCl manifest, as there is no |
271 // corresponding NMF. | 260 // corresponding NMF. |
272 if (!LoadHelperNaClModule(file_handle, nacl_subprocess.get(), params)) { | 261 if (!LoadHelperNaClModule(file_info, |
| 262 nacl_subprocess.get(), |
| 263 params)) { |
273 return NULL; | 264 return NULL; |
274 } | 265 } |
275 // We need not wait for the init_done callback. We can block | 266 // We need not wait for the init_done callback. We can block |
276 // here in StartSrpcServices, since helper NaCl modules | 267 // here in StartSrpcServices, since helper NaCl modules |
277 // are spawned from a private thread. | 268 // are spawned from a private thread. |
278 // | 269 // |
279 // TODO(bsy): if helper module crashes, we should abort. | 270 // TODO(bsy): if helper module crashes, we should abort. |
280 // crash_cb is not used here, so we are relying on crashes | 271 // crash_cb is not used here, so we are relying on crashes |
281 // being detected in StartSrpcServices or later. | 272 // being detected in StartSrpcServices or later. |
282 // | 273 // |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 callback_factory_.Initialize(this); | 315 callback_factory_.Initialize(this); |
325 nacl_interface_ = GetNaClInterface(); | 316 nacl_interface_ = GetNaClInterface(); |
326 CHECK(nacl_interface_ != NULL); | 317 CHECK(nacl_interface_ != NULL); |
327 | 318 |
328 // Notify PPB_NaCl_Private that the instance is created before altering any | 319 // Notify PPB_NaCl_Private that the instance is created before altering any |
329 // state that it tracks. | 320 // state that it tracks. |
330 nacl_interface_->InstanceCreated(pp_instance); | 321 nacl_interface_->InstanceCreated(pp_instance); |
331 // We call set_exit_status() here to ensure that the 'exitStatus' property is | 322 // We call set_exit_status() here to ensure that the 'exitStatus' property is |
332 // set. This can only be called when nacl_interface_ is not NULL. | 323 // set. This can only be called when nacl_interface_ is not NULL. |
333 set_exit_status(-1); | 324 set_exit_status(-1); |
334 nexe_file_info_.handle = PP_kInvalidFileHandle; | 325 nexe_file_info_ = kInvalidNaClFileInfo; |
335 nexe_file_info_.token_lo = 0; | |
336 nexe_file_info_.token_hi = 0; | |
337 } | 326 } |
338 | 327 |
339 | 328 |
340 Plugin::~Plugin() { | 329 Plugin::~Plugin() { |
341 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); | 330 int64_t shutdown_start = NaClGetTimeOfDayMicroseconds(); |
342 | 331 |
343 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p)\n", | 332 PLUGIN_PRINTF(("Plugin::~Plugin (this=%p)\n", |
344 static_cast<void*>(this))); | 333 static_cast<void*>(this))); |
345 // Destroy the coordinator while the rest of the data is still there | 334 // Destroy the coordinator while the rest of the data is still there |
346 pnacl_coordinator_.reset(NULL); | 335 pnacl_coordinator_.reset(NULL); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 | 528 |
540 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, | 529 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, |
541 int exit_status) { | 530 int exit_status) { |
542 DCHECK(pp::Module::Get()->core()->IsMainThread()); | 531 DCHECK(pp::Module::Get()->core()->IsMainThread()); |
543 DCHECK(nacl_interface_); | 532 DCHECK(nacl_interface_); |
544 nacl_interface_->SetExitStatus(pp_instance(), exit_status); | 533 nacl_interface_->SetExitStatus(pp_instance(), exit_status); |
545 } | 534 } |
546 | 535 |
547 | 536 |
548 } // namespace plugin | 537 } // namespace plugin |
OLD | NEW |