| 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 |