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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 | 65 |
66 void Plugin::HistogramTimeSmall(const std::string& name, | 66 void Plugin::HistogramTimeSmall(const std::string& name, |
67 int64_t ms) { | 67 int64_t ms) { |
68 if (ms < 0) return; | 68 if (ms < 0) return; |
69 uma_interface_.HistogramCustomTimes(name, | 69 uma_interface_.HistogramCustomTimes(name, |
70 ms, | 70 ms, |
71 kTimeSmallMin, kTimeSmallMax, | 71 kTimeSmallMin, kTimeSmallMax, |
72 kTimeSmallBuckets); | 72 kTimeSmallBuckets); |
73 } | 73 } |
74 | 74 |
75 bool Plugin::LoadHelperNaClModule(PP_FileHandle file_handle, | 75 bool Plugin::InternalLoadHelperNaClModule(NaClSubprocess* subprocess, |
hidehiko
2014/07/01 05:39:01
nit: "Internal" seems to be usually used as suffix
teravest
2014/07/01 17:48:34
Done.
| |
76 NaClSubprocess* subprocess, | |
77 const SelLdrStartParams& params) { | 76 const SelLdrStartParams& params) { |
hidehiko
2014/07/01 05:39:01
nit: let's align the argument indent.
teravest
2014/07/01 17:48:34
Done.
| |
78 CHECK(!pp::Module::Get()->core()->IsMainThread()); | 77 CHECK(!pp::Module::Get()->core()->IsMainThread()); |
79 ServiceRuntime* service_runtime = | 78 ServiceRuntime* service_runtime = |
80 new ServiceRuntime(this, | 79 new ServiceRuntime(this, |
81 pp_instance(), | 80 pp_instance(), |
82 false, // No main_service_runtime. | 81 false, // No main_service_runtime. |
83 false, // No non-SFI mode (i.e. in SFI-mode). | 82 false, // No non-SFI mode (i.e. in SFI-mode). |
84 pp::BlockUntilComplete(), pp::BlockUntilComplete()); | 83 pp::BlockUntilComplete(), pp::BlockUntilComplete()); |
85 subprocess->set_service_runtime(service_runtime); | 84 subprocess->set_service_runtime(service_runtime); |
86 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " | 85 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " |
87 "(service_runtime=%p)\n", | 86 "(service_runtime=%p)\n", |
(...skipping 13 matching lines...) Expand all Loading... | |
101 if (!service_runtime->WaitForSelLdrStart()) { | 100 if (!service_runtime->WaitForSelLdrStart()) { |
102 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " | 101 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule " |
103 "WaitForSelLdrStart timed out!\n")); | 102 "WaitForSelLdrStart timed out!\n")); |
104 return false; | 103 return false; |
105 } | 104 } |
106 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n", | 105 PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (service_runtime_started=%d)\n", |
107 service_runtime_started)); | 106 service_runtime_started)); |
108 if (!service_runtime_started) | 107 if (!service_runtime_started) |
109 return false; | 108 return false; |
110 | 109 |
111 PP_NaClFileInfo info; | 110 // Now actually start the nexe. |
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. | |
117 // | 111 // |
118 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we | 112 // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we |
119 // have to roll our own blocking logic, similar to WaitForSelLdrStart() | 113 // have to roll our own blocking logic, similar to WaitForSelLdrStart() |
120 // above, except without timeout logic. | 114 // above, except without timeout logic. |
121 pp::Module::Get()->core()->CallOnMainThread( | 115 pp::Module::Get()->core()->CallOnMainThread( |
122 0, | 116 0, |
123 callback_factory_.NewCallback( | 117 callback_factory_.NewCallback( |
hidehiko
2014/07/01 05:39:01
nit: can be fit in a line?
teravest
2014/07/01 17:48:34
Done.
| |
124 &Plugin::LoadNexeAndStart, | 118 &Plugin::StartNexe, |
125 service_runtime, | 119 service_runtime)); |
126 info)); | |
127 return service_runtime->WaitForNexeStart(); | 120 return service_runtime->WaitForNexeStart(); |
128 } | 121 } |
129 | 122 |
130 void Plugin::StartSelLdrOnMainThread(int32_t pp_error, | 123 void Plugin::StartSelLdrOnMainThread(int32_t pp_error, |
131 ServiceRuntime* service_runtime, | 124 ServiceRuntime* service_runtime, |
132 const SelLdrStartParams& params, | 125 const SelLdrStartParams& params, |
133 pp::CompletionCallback callback) { | 126 pp::CompletionCallback callback) { |
134 if (pp_error != PP_OK) { | 127 if (pp_error != PP_OK) { |
135 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg " | 128 PLUGIN_PRINTF(("Plugin::StartSelLdrOnMainThread: non-PP_OK arg " |
136 "-- SHOULD NOT HAPPEN\n")); | 129 "-- SHOULD NOT HAPPEN\n")); |
(...skipping 20 matching lines...) Expand all Loading... | |
157 CHECK(pp::Module::Get()->core()->IsMainThread()); | 150 CHECK(pp::Module::Get()->core()->IsMainThread()); |
158 // Before forking a new sel_ldr process, ensure that we do not leak | 151 // Before forking a new sel_ldr process, ensure that we do not leak |
159 // the ServiceRuntime object for an existing subprocess, and that any | 152 // the ServiceRuntime object for an existing subprocess, and that any |
160 // associated listener threads do not go unjoined because if they | 153 // associated listener threads do not go unjoined because if they |
161 // outlive the Plugin object, they will not be memory safe. | 154 // outlive the Plugin object, they will not be memory safe. |
162 ShutDownSubprocesses(); | 155 ShutDownSubprocesses(); |
163 pp::Var manifest_base_url = | 156 pp::Var manifest_base_url = |
164 pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance())); | 157 pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance())); |
165 std::string manifest_base_url_str = manifest_base_url.AsString(); | 158 std::string manifest_base_url_str = manifest_base_url.AsString(); |
166 | 159 |
167 PP_NaClFileInfo file_info_for_srpc = kInvalidNaClFileInfo; | |
168 PP_NaClFileInfo file_info_for_ipc = kInvalidNaClFileInfo; | |
169 if (uses_nonsfi_mode) { | |
170 // In non-SFI mode, LaunchSelLdr is used to pass the nexe file's descriptor | |
171 // to the NaCl loader process. | |
172 file_info_for_ipc = file_info; | |
173 } else { | |
174 // Otherwise (i.e. in SFI-mode), LoadModule SRPC is still being used. | |
175 file_info_for_srpc = file_info; | |
176 } | |
177 | |
178 SelLdrStartParams params(manifest_base_url_str, | 160 SelLdrStartParams params(manifest_base_url_str, |
179 file_info_for_ipc, | 161 file_info, |
180 true /* uses_irt */, | 162 true /* uses_irt */, |
181 true /* uses_ppapi */, | 163 true /* uses_ppapi */, |
182 enable_dyncode_syscalls, | 164 enable_dyncode_syscalls, |
183 enable_exception_handling, | 165 enable_exception_handling, |
184 enable_crash_throttling); | 166 enable_crash_throttling); |
185 ErrorInfo error_info; | 167 ErrorInfo error_info; |
186 ServiceRuntime* service_runtime = new ServiceRuntime( | 168 ServiceRuntime* service_runtime = new ServiceRuntime( |
187 this, pp_instance(), true, uses_nonsfi_mode, init_done_cb, crash_cb); | 169 this, pp_instance(), true, uses_nonsfi_mode, init_done_cb, crash_cb); |
188 main_subprocess_.set_service_runtime(service_runtime); | 170 main_subprocess_.set_service_runtime(service_runtime); |
189 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", | 171 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", |
190 static_cast<void*>(service_runtime))); | 172 static_cast<void*>(service_runtime))); |
191 if (NULL == service_runtime) { | 173 if (NULL == service_runtime) { |
192 error_info.SetReport( | 174 error_info.SetReport( |
193 PP_NACL_ERROR_SEL_LDR_INIT, | 175 PP_NACL_ERROR_SEL_LDR_INIT, |
194 "sel_ldr init failure " + main_subprocess_.description()); | 176 "sel_ldr init failure " + main_subprocess_.description()); |
195 ReportLoadError(error_info); | 177 ReportLoadError(error_info); |
196 return; | 178 return; |
197 } | 179 } |
198 | 180 |
199 // We don't take any action once nexe loading has completed, so pass an empty | 181 // We don't take any action once nexe loading has completed, so pass an empty |
200 // callback here for |callback|. | 182 // callback here for |callback|. |
201 pp::CompletionCallback callback = callback_factory_.NewCallback( | 183 pp::CompletionCallback callback = callback_factory_.NewCallback( |
202 &Plugin::LoadNexeAndStart, service_runtime, file_info_for_srpc); | 184 &Plugin::StartNexe, service_runtime); |
203 StartSelLdrOnMainThread( | 185 StartSelLdrOnMainThread( |
204 static_cast<int32_t>(PP_OK), service_runtime, params, callback); | 186 static_cast<int32_t>(PP_OK), service_runtime, params, callback); |
205 } | 187 } |
206 | 188 |
207 void Plugin::LoadNexeAndStart(int32_t pp_error, | 189 void Plugin::StartNexe(int32_t pp_error, ServiceRuntime* service_runtime) { |
208 ServiceRuntime* service_runtime, | |
209 PP_NaClFileInfo file_info) { | |
210 CHECK(pp::Module::Get()->core()->IsMainThread()); | 190 CHECK(pp::Module::Get()->core()->IsMainThread()); |
211 if (pp_error != PP_OK) | 191 if (pp_error != PP_OK) |
212 return; | 192 return; |
213 service_runtime->LoadNexeAndStart(file_info); | 193 service_runtime->StartNexe(); |
214 } | 194 } |
215 | 195 |
216 bool Plugin::LoadNaClModuleContinuationIntern() { | 196 bool Plugin::LoadNaClModuleContinuationIntern() { |
217 ErrorInfo error_info; | 197 ErrorInfo error_info; |
218 if (!uses_nonsfi_mode_) { | 198 if (!uses_nonsfi_mode_) { |
219 if (!main_subprocess_.StartSrpcServices()) { | 199 if (!main_subprocess_.StartSrpcServices()) { |
220 // The NaCl process probably crashed. On Linux, a crash causes this | 200 // The NaCl process probably crashed. On Linux, a crash causes this |
221 // error, while on other platforms, the error is detected below, when we | 201 // error, while on other platforms, the error is detected below, when we |
222 // attempt to start the proxy. Report a module initialization error here, | 202 // attempt to start the proxy. Report a module initialization error here, |
223 // to make it less confusing for developers. | 203 // to make it less confusing for developers. |
(...skipping 18 matching lines...) Expand all Loading... | |
242 PP_FileHandle file_handle, | 222 PP_FileHandle file_handle, |
243 ErrorInfo* error_info) { | 223 ErrorInfo* error_info) { |
244 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( | 224 nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( |
245 new NaClSubprocess("helper module", NULL, NULL)); | 225 new NaClSubprocess("helper module", NULL, NULL)); |
246 if (NULL == nacl_subprocess.get()) { | 226 if (NULL == nacl_subprocess.get()) { |
247 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, | 227 error_info->SetReport(PP_NACL_ERROR_SEL_LDR_INIT, |
248 "unable to allocate helper subprocess."); | 228 "unable to allocate helper subprocess."); |
249 return NULL; | 229 return NULL; |
250 } | 230 } |
251 | 231 |
232 PP_NaClFileInfo file_info; | |
233 file_info.handle = file_handle; | |
234 // We never apply validation caching to the PNaCl translator and linker. | |
235 file_info.token_lo = 0; | |
236 file_info.token_hi = 0; | |
237 | |
252 // Do not report UMA stats for translator-related nexes. | 238 // Do not report UMA stats for translator-related nexes. |
253 // TODO(sehr): define new UMA stats for translator related nexe events. | 239 // 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 | 240 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is |
255 // done to save on address space and swap space. | 241 // done to save on address space and swap space. |
256 // | |
257 // Currently, this works only in SFI-mode. So, LoadModule SRPC is still used. | |
258 // So, pass kInvalidNaClFileInfo here, and instead |file_handle| is passed | |
259 // to LoadNaClModuleFromBackgroundThread() below. | |
260 // TODO(teravest, hidehiko): Pass file_handle to params, so that LaunchSelLdr | |
261 // will look at the info. | |
262 SelLdrStartParams params(helper_url, | 242 SelLdrStartParams params(helper_url, |
263 kInvalidNaClFileInfo, | 243 file_info, |
264 false /* uses_irt */, | 244 false /* uses_irt */, |
265 false /* uses_ppapi */, | 245 false /* uses_ppapi */, |
266 false /* enable_dyncode_syscalls */, | 246 false /* enable_dyncode_syscalls */, |
267 false /* enable_exception_handling */, | 247 false /* enable_exception_handling */, |
268 true /* enable_crash_throttling */); | 248 true /* enable_crash_throttling */); |
269 | 249 |
270 // Helper NaCl modules always use the PNaCl manifest, as there is no | 250 // Helper NaCl modules always use the PNaCl manifest, as there is no |
271 // corresponding NMF. | 251 // corresponding NMF. |
272 if (!LoadHelperNaClModule(file_handle, nacl_subprocess.get(), params)) { | 252 if (!InternalLoadHelperNaClModule(nacl_subprocess.get(), params)) { |
273 return NULL; | 253 return NULL; |
274 } | 254 } |
275 // We need not wait for the init_done callback. We can block | 255 // We need not wait for the init_done callback. We can block |
276 // here in StartSrpcServices, since helper NaCl modules | 256 // here in StartSrpcServices, since helper NaCl modules |
277 // are spawned from a private thread. | 257 // are spawned from a private thread. |
278 // | 258 // |
279 // TODO(bsy): if helper module crashes, we should abort. | 259 // TODO(bsy): if helper module crashes, we should abort. |
280 // crash_cb is not used here, so we are relying on crashes | 260 // crash_cb is not used here, so we are relying on crashes |
281 // being detected in StartSrpcServices or later. | 261 // being detected in StartSrpcServices or later. |
282 // | 262 // |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
539 | 519 |
540 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, | 520 void Plugin::SetExitStatusOnMainThread(int32_t pp_error, |
541 int exit_status) { | 521 int exit_status) { |
542 DCHECK(pp::Module::Get()->core()->IsMainThread()); | 522 DCHECK(pp::Module::Get()->core()->IsMainThread()); |
543 DCHECK(nacl_interface_); | 523 DCHECK(nacl_interface_); |
544 nacl_interface_->SetExitStatus(pp_instance(), exit_status); | 524 nacl_interface_->SetExitStatus(pp_instance(), exit_status); |
545 } | 525 } |
546 | 526 |
547 | 527 |
548 } // namespace plugin | 528 } // namespace plugin |
OLD | NEW |