OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime" | 7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime" |
8 | 8 |
9 #include "components/nacl/renderer/plugin/service_runtime.h" | 9 #include "components/nacl/renderer/plugin/service_runtime.h" |
10 | 10 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 bool ServiceRuntime::StartModule() { | 81 bool ServiceRuntime::StartModule() { |
82 // start the module. otherwise we cannot connect for multimedia | 82 // start the module. otherwise we cannot connect for multimedia |
83 // subsystem since that is handled by user-level code (not secure!) | 83 // subsystem since that is handled by user-level code (not secure!) |
84 // in libsrpc. | 84 // in libsrpc. |
85 int load_status = -1; | 85 int load_status = -1; |
86 if (uses_nonsfi_mode_) { | 86 if (uses_nonsfi_mode_) { |
87 // In non-SFI mode, we don't need to call start_module SRPC to launch | 87 // In non-SFI mode, we don't need to call start_module SRPC to launch |
88 // the plugin. | 88 // the plugin. |
89 load_status = LOAD_OK; | 89 load_status = LOAD_OK; |
90 } else { | 90 } else { |
91 // We invoke start_module to unblock NaClWaitForStartModuleCommand in | |
92 // sel_main_chrome.c on the NaCl side, but the load_status is obtained by | |
93 // a different hook. Remove this once NaClWaitForStartModuleCommand is no | |
94 // longer needed. | |
91 NaClSrpcResultCodes rpc_result = | 95 NaClSrpcResultCodes rpc_result = |
92 NaClSrpcInvokeBySignature(&command_channel_, | 96 NaClSrpcInvokeBySignature(&command_channel_, |
93 "start_module::i", | 97 "start_module::i", |
94 &load_status); | 98 &load_status); |
95 | 99 |
96 if (NACL_SRPC_RESULT_OK != rpc_result) { | 100 if (NACL_SRPC_RESULT_OK != rpc_result) { |
97 ErrorInfo error_info; | 101 ErrorInfo error_info; |
98 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_START_MODULE, | 102 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_START_MODULE, |
99 "ServiceRuntime: could not start nacl module"); | 103 "ServiceRuntime: could not start nacl module"); |
100 ReportLoadError(error_info); | 104 ReportLoadError(error_info); |
101 return false; | 105 return false; |
102 } | 106 } |
103 } | 107 } |
104 | 108 |
105 NaClLog(4, "ServiceRuntime::StartModule (load_status=%d)\n", load_status); | 109 NaClLog(4, "ServiceRuntime::StartModule (load_status=%d)\n", load_status); |
106 if (main_service_runtime_) { | 110 return LOAD_OK == load_status; |
107 if (load_status < 0 || load_status > NACL_ERROR_CODE_MAX) | |
108 load_status = LOAD_STATUS_UNKNOWN; | |
109 GetNaClInterface()->ReportSelLdrStatus(pp_instance_, | |
jvoung (off chromium)
2015/04/21 17:11:21
Also removed this, now that it isn't used.
| |
110 load_status, | |
111 NACL_ERROR_CODE_MAX); | |
112 } | |
113 | |
114 if (LOAD_OK != load_status) { | |
115 ErrorInfo error_info; | |
116 error_info.SetReport( | |
117 PP_NACL_ERROR_SEL_LDR_START_STATUS, | |
118 NaClErrorString(static_cast<NaClErrorCode>(load_status))); | |
119 ReportLoadError(error_info); | |
120 return false; | |
121 } | |
122 return true; | |
123 } | 111 } |
124 | 112 |
125 void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params, | 113 void ServiceRuntime::StartSelLdr(const SelLdrStartParams& params, |
126 pp::CompletionCallback callback) { | 114 pp::CompletionCallback callback) { |
127 NaClLog(4, "ServiceRuntime::Start\n"); | 115 NaClLog(4, "ServiceRuntime::Start\n"); |
128 | 116 |
129 nacl::scoped_ptr<SelLdrLauncherChrome> | 117 nacl::scoped_ptr<SelLdrLauncherChrome> |
130 tmp_subprocess(new SelLdrLauncherChrome()); | 118 tmp_subprocess(new SelLdrLauncherChrome()); |
131 if (NULL == tmp_subprocess.get()) { | 119 if (NULL == tmp_subprocess.get()) { |
132 NaClLog(LOG_ERROR, "ServiceRuntime::Start (subprocess create failed)\n"); | 120 NaClLog(LOG_ERROR, "ServiceRuntime::Start (subprocess create failed)\n"); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 nacl::MutexLocker take(&mu_); | 189 nacl::MutexLocker take(&mu_); |
202 start_nexe_done_ = true; | 190 start_nexe_done_ = true; |
203 nexe_started_ok_ = ok; | 191 nexe_started_ok_ = ok; |
204 NaClXCondVarSignal(&cond_); | 192 NaClXCondVarSignal(&cond_); |
205 } | 193 } |
206 | 194 |
207 void ServiceRuntime::StartNexe() { | 195 void ServiceRuntime::StartNexe() { |
208 bool ok = StartNexeInternal(); | 196 bool ok = StartNexeInternal(); |
209 if (ok) { | 197 if (ok) { |
210 NaClLog(4, "ServiceRuntime::StartNexe (success)\n"); | 198 NaClLog(4, "ServiceRuntime::StartNexe (success)\n"); |
211 } else { | |
212 ReapLogs(); | |
213 } | 199 } |
214 // This only matters if a background thread is waiting, but we signal in all | 200 // This only matters if a background thread is waiting, but we signal in all |
215 // cases to simplify the code. | 201 // cases to simplify the code. |
216 SignalNexeStarted(ok); | 202 SignalNexeStarted(ok); |
217 } | 203 } |
218 | 204 |
219 bool ServiceRuntime::StartNexeInternal() { | 205 bool ServiceRuntime::StartNexeInternal() { |
220 if (!SetupCommandChannel()) | 206 if (!SetupCommandChannel()) |
221 return false; | 207 return false; |
222 return StartModule(); | 208 return StartModule(); |
223 } | 209 } |
224 | 210 |
225 void ServiceRuntime::ReapLogs() { | |
226 // TODO(teravest): We should allow the NaCl process to crash itself when a | |
227 // module fails to start, and remove the call to RemoteLog() here. The | |
228 // reverse channel is no longer needed for crash reporting. | |
229 // | |
230 // The reasoning behind the current code behavior follows: | |
231 // On a load failure the NaCl process does not crash itself to | |
232 // avoid a race where the no-more-senders error on the reverse | |
233 // channel service thread might cause the crash-detection logic to | |
234 // kick in before the start_module RPC reply has been received. So | |
235 // we induce a NaCl process crash here. | |
236 RemoteLog(LOG_FATAL, "reap logs\n"); | |
237 | |
238 // TODO(teravest): Release subprocess_ here since it's no longer needed. It | |
239 // was previously kept around to collect crash log output from the bootstrap | |
240 // channel. | |
241 } | |
242 | |
243 void ServiceRuntime::ReportLoadError(const ErrorInfo& error_info) { | 211 void ServiceRuntime::ReportLoadError(const ErrorInfo& error_info) { |
244 if (main_service_runtime_) { | 212 if (main_service_runtime_) { |
245 plugin_->ReportLoadError(error_info); | 213 plugin_->ReportLoadError(error_info); |
246 } | 214 } |
247 } | 215 } |
248 | 216 |
249 SrpcClient* ServiceRuntime::SetupAppChannel() { | 217 SrpcClient* ServiceRuntime::SetupAppChannel() { |
250 NaClLog(4, "ServiceRuntime::SetupAppChannel (subprocess_=%p)\n", | 218 NaClLog(4, "ServiceRuntime::SetupAppChannel (subprocess_=%p)\n", |
251 reinterpret_cast<void*>(subprocess_.get())); | 219 reinterpret_cast<void*>(subprocess_.get())); |
252 nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect(); | 220 nacl::DescWrapper* connect_desc = subprocess_->socket_addr()->Connect(); |
253 if (NULL == connect_desc) { | 221 if (NULL == connect_desc) { |
254 NaClLog(LOG_ERROR, "ServiceRuntime::SetupAppChannel (connect failed)\n"); | 222 NaClLog(LOG_ERROR, "ServiceRuntime::SetupAppChannel (connect failed)\n"); |
255 return NULL; | 223 return NULL; |
256 } else { | 224 } else { |
257 NaClLog(4, "ServiceRuntime::SetupAppChannel (conect_desc=%p)\n", | 225 NaClLog(4, "ServiceRuntime::SetupAppChannel (conect_desc=%p)\n", |
258 static_cast<void*>(connect_desc)); | 226 static_cast<void*>(connect_desc)); |
259 SrpcClient* srpc_client = SrpcClient::New(connect_desc); | 227 SrpcClient* srpc_client = SrpcClient::New(connect_desc); |
260 NaClLog(4, "ServiceRuntime::SetupAppChannel (srpc_client=%p)\n", | 228 NaClLog(4, "ServiceRuntime::SetupAppChannel (srpc_client=%p)\n", |
261 static_cast<void*>(srpc_client)); | 229 static_cast<void*>(srpc_client)); |
262 delete connect_desc; | 230 delete connect_desc; |
263 return srpc_client; | 231 return srpc_client; |
264 } | 232 } |
265 } | 233 } |
266 | 234 |
267 bool ServiceRuntime::RemoteLog(int severity, const std::string& msg) { | |
268 NaClSrpcResultCodes rpc_result = | |
269 NaClSrpcInvokeBySignature(&command_channel_, | |
270 "log:is:", | |
271 severity, | |
272 strdup(msg.c_str())); | |
273 return (NACL_SRPC_RESULT_OK == rpc_result); | |
274 } | |
275 | |
276 void ServiceRuntime::Shutdown() { | 235 void ServiceRuntime::Shutdown() { |
277 // Abandon callbacks, tell service threads to quit if they were | 236 // Abandon callbacks, tell service threads to quit if they were |
278 // blocked waiting for main thread operations to finish. Note that | 237 // blocked waiting for main thread operations to finish. Note that |
279 // some callbacks must still await their completion event, e.g., | 238 // some callbacks must still await their completion event, e.g., |
280 // CallOnMainThread must still wait for the time out, or I/O events | 239 // CallOnMainThread must still wait for the time out, or I/O events |
281 // must finish, so resources associated with pending events cannot | 240 // must finish, so resources associated with pending events cannot |
282 // be deallocated. | 241 // be deallocated. |
283 | 242 |
284 // Note that this does waitpid() to get rid of any zombie subprocess. | 243 // Note that this does waitpid() to get rid of any zombie subprocess. |
285 subprocess_.reset(NULL); | 244 subprocess_.reset(NULL); |
286 | 245 |
287 NaClSrpcDtor(&command_channel_); | 246 NaClSrpcDtor(&command_channel_); |
288 } | 247 } |
289 | 248 |
290 ServiceRuntime::~ServiceRuntime() { | 249 ServiceRuntime::~ServiceRuntime() { |
291 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n", | 250 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n", |
292 static_cast<void*>(this)); | 251 static_cast<void*>(this)); |
293 // We do this just in case Shutdown() was not called. | 252 // We do this just in case Shutdown() was not called. |
294 subprocess_.reset(NULL); | 253 subprocess_.reset(NULL); |
295 | 254 |
296 NaClCondVarDtor(&cond_); | 255 NaClCondVarDtor(&cond_); |
297 NaClMutexDtor(&mu_); | 256 NaClMutexDtor(&mu_); |
298 } | 257 } |
299 | 258 |
300 } // namespace plugin | 259 } // namespace plugin |
OLD | NEW |