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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 namespace plugin { | 43 namespace plugin { |
44 | 44 |
45 namespace { | 45 namespace { |
46 | 46 |
47 // Up to 20 seconds | 47 // Up to 20 seconds |
48 const int64_t kTimeSmallMin = 1; // in ms | 48 const int64_t kTimeSmallMin = 1; // in ms |
49 const int64_t kTimeSmallMax = 20000; // in ms | 49 const int64_t kTimeSmallMax = 20000; // in ms |
50 const uint32_t kTimeSmallBuckets = 100; | 50 const uint32_t kTimeSmallBuckets = 100; |
51 | 51 |
52 // Converts a PP_FileHandle to a POSIX file descriptor. | |
53 int32_t ConvertFileDescriptor(PP_FileHandle handle) { | |
54 PLUGIN_PRINTF(("ConvertFileDescriptor, handle=%d\n", handle)); | |
55 #if NACL_WINDOWS | |
56 int32_t file_desc = NACL_NO_FILE_DESC; | |
57 // On Windows, valid handles are 32 bit unsigned integers so this is safe. | |
58 file_desc = reinterpret_cast<intptr_t>(handle); | |
59 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor. | |
60 int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY); | |
61 if (posix_desc == -1) { | |
62 // Close the Windows HANDLE if it can't be converted. | |
63 CloseHandle(reinterpret_cast<HANDLE>(file_desc)); | |
64 return -1; | |
65 } | |
66 return posix_desc; | |
67 #else | |
68 return handle; | |
69 #endif | |
70 } | |
71 | |
72 | |
73 } // namespace | 52 } // namespace |
74 | 53 |
75 void Plugin::ShutDownSubprocesses() { | 54 void Plugin::ShutDownSubprocesses() { |
76 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", | 55 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (this=%p)\n", |
77 static_cast<void*>(this))); | 56 static_cast<void*>(this))); |
78 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", | 57 PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", |
79 main_subprocess_.detailed_description().c_str())); | 58 main_subprocess_.detailed_description().c_str())); |
80 | 59 |
81 // Shut down service runtime. This must be done before all other calls so | 60 // Shut down service runtime. This must be done before all other calls so |
82 // they don't block forever when waiting for the upcall thread to exit. | 61 // they don't block forever when waiting for the upcall thread to exit. |
(...skipping 21 matching lines...) Expand all Loading... |
104 NACL_ERROR_CODE_MAX); | 83 NACL_ERROR_CODE_MAX); |
105 | 84 |
106 // Gather data to see if being installed changes load outcomes. | 85 // Gather data to see if being installed changes load outcomes. |
107 const char* name = nacl_interface_->GetIsInstalled(pp_instance()) ? | 86 const char* name = nacl_interface_->GetIsInstalled(pp_instance()) ? |
108 "NaCl.LoadStatus.SelLdr.InstalledApp" : | 87 "NaCl.LoadStatus.SelLdr.InstalledApp" : |
109 "NaCl.LoadStatus.SelLdr.NotInstalledApp"; | 88 "NaCl.LoadStatus.SelLdr.NotInstalledApp"; |
110 uma_interface_.HistogramEnumeration(name, error_code, NACL_ERROR_CODE_MAX); | 89 uma_interface_.HistogramEnumeration(name, error_code, NACL_ERROR_CODE_MAX); |
111 } | 90 } |
112 | 91 |
113 bool Plugin::LoadNaClModuleFromBackgroundThread( | 92 bool Plugin::LoadNaClModuleFromBackgroundThread( |
114 nacl::DescWrapper* wrapper, | 93 PP_FileHandle file_handle, |
115 NaClSubprocess* subprocess, | 94 NaClSubprocess* subprocess, |
116 int32_t manifest_id, | 95 int32_t manifest_id, |
117 const SelLdrStartParams& params) { | 96 const SelLdrStartParams& params) { |
118 CHECK(!pp::Module::Get()->core()->IsMainThread()); | 97 CHECK(!pp::Module::Get()->core()->IsMainThread()); |
119 ServiceRuntime* service_runtime = | 98 ServiceRuntime* service_runtime = |
120 new ServiceRuntime(this, manifest_id, false, uses_nonsfi_mode_, | 99 new ServiceRuntime(this, manifest_id, false, uses_nonsfi_mode_, |
121 pp::BlockUntilComplete(), pp::BlockUntilComplete()); | 100 pp::BlockUntilComplete(), pp::BlockUntilComplete()); |
122 subprocess->set_service_runtime(service_runtime); | 101 subprocess->set_service_runtime(service_runtime); |
123 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " | 102 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " |
124 "(service_runtime=%p)\n", | 103 "(service_runtime=%p)\n", |
(...skipping 11 matching lines...) Expand all Loading... |
136 sel_ldr_callback); | 115 sel_ldr_callback); |
137 pp::Module::Get()->core()->CallOnMainThread(0, callback, 0); | 116 pp::Module::Get()->core()->CallOnMainThread(0, callback, 0); |
138 if (!service_runtime->WaitForSelLdrStart()) { | 117 if (!service_runtime->WaitForSelLdrStart()) { |
139 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " | 118 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " |
140 "WaitForSelLdrStart timed out!\n")); | 119 "WaitForSelLdrStart timed out!\n")); |
141 return false; | 120 return false; |
142 } | 121 } |
143 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " | 122 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " |
144 "(service_runtime_started=%d)\n", | 123 "(service_runtime_started=%d)\n", |
145 service_runtime_started)); | 124 service_runtime_started)); |
146 if (!service_runtime_started) { | 125 if (!service_runtime_started) |
147 return false; | 126 return false; |
148 } | 127 |
| 128 // TODO(teravest): Get rid of this conversion to DescWrapper. |
| 129 int32_t fd = ConvertFileDescriptor(file_handle, true); |
| 130 nacl::DescWrapper* wrapper = wrapper_factory()->MakeFileDesc(fd, O_RDONLY); |
149 | 131 |
150 // Now actually load the nexe, which can happen on a background thread. | 132 // Now actually load the nexe, which can happen on a background thread. |
151 bool nexe_loaded = service_runtime->LoadNexeAndStart( | 133 bool nexe_loaded = service_runtime->LoadNexeAndStart( |
152 wrapper, pp::BlockUntilComplete()); | 134 wrapper, pp::BlockUntilComplete()); |
153 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " | 135 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " |
154 "(nexe_loaded=%d)\n", | 136 "(nexe_loaded=%d)\n", |
155 nexe_loaded)); | 137 nexe_loaded)); |
156 return nexe_loaded; | 138 return nexe_loaded; |
157 } | 139 } |
158 | 140 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 | 244 |
263 bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance())); | 245 bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance())); |
264 if (result) { | 246 if (result) { |
265 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", | 247 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", |
266 main_subprocess_.detailed_description().c_str())); | 248 main_subprocess_.detailed_description().c_str())); |
267 } | 249 } |
268 return result; | 250 return result; |
269 } | 251 } |
270 | 252 |
271 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, | 253 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, |
272 nacl::DescWrapper* wrapper, | 254 PP_FileHandle file_handle, |
273 int32_t manifest_id, | 255 int32_t manifest_id, |
274 ErrorInfo* error_info) { | 256 ErrorInfo* error_info) { |
275 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( | 257 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( |
276 new NaClSubprocess("helper module", NULL, NULL)); | 258 new NaClSubprocess("helper module", NULL, NULL)); |
277 if (NULL == nacl_subprocess.get()) { | 259 if (NULL == nacl_subprocess.get()) { |
278 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, | 260 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, |
279 "unable to allocate helper subprocess."); | 261 "unable to allocate helper subprocess."); |
280 return NULL; | 262 return NULL; |
281 } | 263 } |
282 | 264 |
283 // Do not report UMA stats for translator-related nexes. | 265 // Do not report UMA stats for translator-related nexes. |
284 // TODO(sehr): define new UMA stats for translator related nexe events. | 266 // TODO(sehr): define new UMA stats for translator related nexe events. |
285 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is | 267 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is |
286 // done to save on address space and swap space. | 268 // done to save on address space and swap space. |
287 // TODO(jvoung): See if we still need the uses_ppapi variable, now that | 269 // TODO(jvoung): See if we still need the uses_ppapi variable, now that |
288 // LaunchSelLdr always happens on the main thread. | 270 // LaunchSelLdr always happens on the main thread. |
289 bool enable_dev_interfaces = | 271 bool enable_dev_interfaces = |
290 nacl_interface_->DevInterfacesEnabled(pp_instance()); | 272 nacl_interface_->DevInterfacesEnabled(pp_instance()); |
291 SelLdrStartParams params(helper_url, | 273 SelLdrStartParams params(helper_url, |
292 false /* uses_irt */, | 274 false /* uses_irt */, |
293 false /* uses_ppapi */, | 275 false /* uses_ppapi */, |
294 false /* uses_nonsfi_mode */, | 276 false /* uses_nonsfi_mode */, |
295 enable_dev_interfaces, | 277 enable_dev_interfaces, |
296 false /* enable_dyncode_syscalls */, | 278 false /* enable_dyncode_syscalls */, |
297 false /* enable_exception_handling */, | 279 false /* enable_exception_handling */, |
298 true /* enable_crash_throttling */); | 280 true /* enable_crash_throttling */); |
299 if (!LoadNaClModuleFromBackgroundThread(wrapper, nacl_subprocess.get(), | 281 if (!LoadNaClModuleFromBackgroundThread(file_handle, nacl_subprocess.get(), |
300 manifest_id, params)) { | 282 manifest_id, params)) { |
301 return NULL; | 283 return NULL; |
302 } | 284 } |
303 // We need not wait for the init_done callback. We can block | 285 // We need not wait for the init_done callback. We can block |
304 // here in StartSrpcServices, since helper NaCl modules | 286 // here in StartSrpcServices, since helper NaCl modules |
305 // are spawned from a private thread. | 287 // are spawned from a private thread. |
306 // | 288 // |
307 // TODO(bsy): if helper module crashes, we should abort. | 289 // TODO(bsy): if helper module crashes, we should abort. |
308 // crash_cb is not used here, so we are relying on crashes | 290 // crash_cb is not used here, so we are relying on crashes |
309 // being detected in StartSrpcServices or later. | 291 // being detected in StartSrpcServices or later. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 static_cast<void*>(this))); | 410 static_cast<void*>(this))); |
429 // We don't know if the plugin will handle the document load, but return | 411 // We don't know if the plugin will handle the document load, but return |
430 // true in order to give it a chance to respond once the proxy is started. | 412 // true in order to give it a chance to respond once the proxy is started. |
431 return true; | 413 return true; |
432 } | 414 } |
433 | 415 |
434 void Plugin::NexeFileDidOpen(int32_t pp_error) { | 416 void Plugin::NexeFileDidOpen(int32_t pp_error) { |
435 if (pp_error != PP_OK) | 417 if (pp_error != PP_OK) |
436 return; | 418 return; |
437 | 419 |
438 int32_t desc = ConvertFileDescriptor(nexe_handle_); | 420 int32_t desc = ConvertFileDescriptor(nexe_handle_, true); |
439 nexe_handle_ = PP_kInvalidFileHandle; // Clear out nexe handle. | 421 nexe_handle_ = PP_kInvalidFileHandle; // Clear out nexe handle. |
440 | 422 |
441 nacl::scoped_ptr<nacl::DescWrapper> | 423 nacl::scoped_ptr<nacl::DescWrapper> |
442 wrapper(wrapper_factory()->MakeFileDesc(desc, O_RDONLY)); | 424 wrapper(wrapper_factory()->MakeFileDesc(desc, O_RDONLY)); |
443 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); | 425 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); |
444 LoadNaClModule( | 426 LoadNaClModule( |
445 wrapper.release(), | 427 wrapper.release(), |
446 uses_nonsfi_mode_, | 428 uses_nonsfi_mode_, |
447 true, /* enable_dyncode_syscalls */ | 429 true, /* enable_dyncode_syscalls */ |
448 true, /* enable_exception_handling */ | 430 true, /* enable_exception_handling */ |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 | 750 |
769 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, | 751 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, |
770 int exit_status) { | 752 int exit_status) { |
771 DCHECK(pp::Module::Get()->core()->IsMainThread()); | 753 DCHECK(pp::Module::Get()->core()->IsMainThread()); |
772 DCHECK(nacl_interface_); | 754 DCHECK(nacl_interface_); |
773 nacl_interface_->SetExitStatus(pp_instance(), exit_status); | 755 nacl_interface_->SetExitStatus(pp_instance(), exit_status); |
774 } | 756 } |
775 | 757 |
776 | 758 |
777 } // namespace plugin | 759 } // namespace plugin |
OLD | NEW |