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 "native_client/src/trusted/plugin/service_runtime.h" | 9 #include "native_client/src/trusted/plugin/service_runtime.h" |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... | |
39 // PostMessage method, so this undef must appear before any of those. | 39 // PostMessage method, so this undef must appear before any of those. |
40 #ifdef PostMessage | 40 #ifdef PostMessage |
41 #undef PostMessage | 41 #undef PostMessage |
42 #endif | 42 #endif |
43 #include "native_client/src/trusted/plugin/plugin.h" | 43 #include "native_client/src/trusted/plugin/plugin.h" |
44 #include "native_client/src/trusted/plugin/plugin_error.h" | 44 #include "native_client/src/trusted/plugin/plugin_error.h" |
45 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" | 45 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" |
46 #include "native_client/src/trusted/plugin/pnacl_resources.h" | 46 #include "native_client/src/trusted/plugin/pnacl_resources.h" |
47 #include "native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h" | 47 #include "native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h" |
48 #include "native_client/src/trusted/plugin/srpc_client.h" | 48 #include "native_client/src/trusted/plugin/srpc_client.h" |
49 | 49 #include "native_client/src/trusted/reverse_service/nacl_file_info.h" |
50 #include "native_client/src/trusted/weak_ref/call_on_main_thread.h" | |
51 | |
52 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | 50 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
53 #include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h" | 51 #include "native_client/src/trusted/service_runtime/include/sys/nacl_imc_api.h" |
52 #include "native_client/src/trusted/weak_ref/call_on_main_thread.h" | |
54 | 53 |
55 #include "ppapi/c/pp_errors.h" | 54 #include "ppapi/c/pp_errors.h" |
56 #include "ppapi/c/trusted/ppb_file_io_trusted.h" | 55 #include "ppapi/c/trusted/ppb_file_io_trusted.h" |
57 #include "ppapi/cpp/core.h" | 56 #include "ppapi/cpp/core.h" |
58 #include "ppapi/cpp/completion_callback.h" | 57 #include "ppapi/cpp/completion_callback.h" |
59 #include "ppapi/cpp/file_io.h" | 58 #include "ppapi/cpp/file_io.h" |
60 | 59 |
61 namespace { | 60 namespace { |
62 | 61 |
63 // For doing crude quota enforcement on writes to temp files. | 62 // For doing crude quota enforcement on writes to temp files. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 return false; | 164 return false; |
166 } | 165 } |
167 | 166 |
168 return true; | 167 return true; |
169 } | 168 } |
170 | 169 |
171 // TODO(bsy): OpenManifestEntry should use the manifest to ResolveKey | 170 // TODO(bsy): OpenManifestEntry should use the manifest to ResolveKey |
172 // and invoke StreamAsFile with a completion callback that invokes | 171 // and invoke StreamAsFile with a completion callback that invokes |
173 // GetPOSIXFileDesc. | 172 // GetPOSIXFileDesc. |
174 bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key, | 173 bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key, |
175 int32_t* out_desc) { | 174 struct NaClFileInfo *info) { |
176 ErrorInfo error_info; | 175 ErrorInfo error_info; |
177 bool op_complete = false; // NB: mu_ and cv_ also controls access to this! | 176 bool op_complete = false; // NB: mu_ and cv_ also controls access to this! |
177 // The to_open object is owned by the weak ref callback. Because this function | |
178 // waits for the callback to finish, the to_open object will be deallocated on | |
179 // the main thread before this function can return. The pointers it contains | |
180 // to stack variables will not leak. | |
178 OpenManifestEntryResource* to_open = | 181 OpenManifestEntryResource* to_open = |
179 new OpenManifestEntryResource(url_key, out_desc, | 182 new OpenManifestEntryResource(url_key, info, |
180 &error_info, &op_complete); | 183 &error_info, &op_complete); |
181 CHECK(to_open != NULL); | 184 CHECK(to_open != NULL); |
182 NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n", | 185 NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n", |
183 url_key.c_str()); | 186 url_key.c_str()); |
184 // This assumes we are not on the main thread. If false, we deadlock. | 187 // This assumes we are not on the main thread. If false, we deadlock. |
185 plugin::WeakRefCallOnMainThread( | 188 plugin::WeakRefCallOnMainThread( |
186 anchor_, | 189 anchor_, |
187 0, | 190 0, |
188 this, | 191 this, |
189 &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation, | 192 &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 // The caller is responsible for not closing *out_desc. If it is | 224 // The caller is responsible for not closing *out_desc. If it is |
222 // closed prematurely, then another open could re-use the OS | 225 // closed prematurely, then another open could re-use the OS |
223 // descriptor, confusing the opened_ map. If the caller is going to | 226 // descriptor, confusing the opened_ map. If the caller is going to |
224 // want to make a NaClDesc object and transfer it etc., then the | 227 // want to make a NaClDesc object and transfer it etc., then the |
225 // caller should DUP the descriptor (but remember the original | 228 // caller should DUP the descriptor (but remember the original |
226 // value) for use by the NaClDesc object, which closes when the | 229 // value) for use by the NaClDesc object, which closes when the |
227 // object is destroyed. | 230 // object is destroyed. |
228 NaClLog(4, | 231 NaClLog(4, |
229 "PluginReverseInterface::OpenManifestEntry:" | 232 "PluginReverseInterface::OpenManifestEntry:" |
230 " *out_desc = %d\n", | 233 " *out_desc = %d\n", |
231 *out_desc); | 234 info->desc); |
232 if (*out_desc == -1) { | 235 if (info->desc == -1) { |
233 // TODO(bsy,ncbray): what else should we do with the error? This | 236 // TODO(bsy,ncbray): what else should we do with the error? This |
234 // is a runtime error that may simply be a programming error in | 237 // is a runtime error that may simply be a programming error in |
235 // the untrusted code, or it may be something else wrong w/ the | 238 // the untrusted code, or it may be something else wrong w/ the |
236 // manifest. | 239 // manifest. |
237 NaClLog(4, | 240 NaClLog(4, |
238 "OpenManifestEntry: failed for key %s, code %d (%s)\n", | 241 "OpenManifestEntry: failed for key %s, code %d (%s)\n", |
239 url_key.c_str(), | 242 url_key.c_str(), |
240 error_info.error_code(), | 243 error_info.error_code(), |
241 error_info.message().c_str()); | 244 error_info.message().c_str()); |
242 } | 245 } |
(...skipping 17 matching lines...) Expand all Loading... | |
260 | 263 |
261 std::string mapped_url; | 264 std::string mapped_url; |
262 PnaclOptions pnacl_options; | 265 PnaclOptions pnacl_options; |
263 if (!manifest_->ResolveKey(p->url, &mapped_url, | 266 if (!manifest_->ResolveKey(p->url, &mapped_url, |
264 &pnacl_options, p->error_info)) { | 267 &pnacl_options, p->error_info)) { |
265 NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); | 268 NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); |
266 // Failed, and error_info has the details on what happened. Wake | 269 // Failed, and error_info has the details on what happened. Wake |
267 // up requesting thread -- we are done. | 270 // up requesting thread -- we are done. |
268 nacl::MutexLocker take(&mu_); | 271 nacl::MutexLocker take(&mu_); |
269 *p->op_complete_ptr = true; // done... | 272 *p->op_complete_ptr = true; // done... |
270 *p->out_desc = -1; // but failed. | 273 p->file_info->desc = -1; // but failed. |
271 NaClXCondVarBroadcast(&cv_); | 274 NaClXCondVarBroadcast(&cv_); |
272 return; | 275 return; |
273 } | 276 } |
274 NaClLog(4, | 277 NaClLog(4, |
275 "OpenManifestEntry_MainThreadContinuation: " | 278 "OpenManifestEntry_MainThreadContinuation: " |
276 "ResolveKey: %s -> %s (pnacl_translate(%d))\n", | 279 "ResolveKey: %s -> %s (pnacl_translate(%d))\n", |
277 p->url.c_str(), mapped_url.c_str(), pnacl_options.translate()); | 280 p->url.c_str(), mapped_url.c_str(), pnacl_options.translate()); |
278 | 281 |
279 open_cont = new OpenManifestEntryResource(*p); // copy ctor! | 282 open_cont = new OpenManifestEntryResource(*p); // copy ctor! |
280 CHECK(open_cont != NULL); | 283 CHECK(open_cont != NULL); |
281 open_cont->url = mapped_url; | 284 open_cont->url = mapped_url; |
282 if (!pnacl_options.translate()) { | 285 if (!pnacl_options.translate()) { |
283 pp::CompletionCallback stream_cc = WeakRefNewCallback( | 286 pp::CompletionCallback stream_cc = WeakRefNewCallback( |
284 anchor_, | 287 anchor_, |
285 this, | 288 this, |
286 &PluginReverseInterface::StreamAsFile_MainThreadContinuation, | 289 &PluginReverseInterface::StreamAsFile_MainThreadContinuation, |
287 open_cont); | 290 open_cont); |
288 // Normal files. | 291 // Normal files. |
289 if (!PnaclUrls::IsPnaclComponent(mapped_url)) { | 292 if (!PnaclUrls::IsPnaclComponent(mapped_url)) { |
290 if (!plugin_->StreamAsFile(mapped_url, | 293 if (!plugin_->StreamAsFile(mapped_url, |
291 stream_cc.pp_completion_callback())) { | 294 stream_cc.pp_completion_callback())) { |
292 NaClLog(4, | 295 NaClLog(4, |
293 "OpenManifestEntry_MainThreadContinuation: " | 296 "OpenManifestEntry_MainThreadContinuation: " |
294 "StreamAsFile failed\n"); | 297 "StreamAsFile failed\n"); |
295 nacl::MutexLocker take(&mu_); | 298 nacl::MutexLocker take(&mu_); |
296 *p->op_complete_ptr = true; // done... | 299 *p->op_complete_ptr = true; // done... |
297 *p->out_desc = -1; // but failed. | 300 p->file_info->desc = -1; // but failed. |
298 p->error_info->SetReport(ERROR_MANIFEST_OPEN, | 301 p->error_info->SetReport(ERROR_MANIFEST_OPEN, |
299 "ServiceRuntime: StreamAsFile failed"); | 302 "ServiceRuntime: StreamAsFile failed"); |
300 NaClXCondVarBroadcast(&cv_); | 303 NaClXCondVarBroadcast(&cv_); |
301 return; | 304 return; |
302 } | 305 } |
303 NaClLog(4, | 306 NaClLog(4, |
304 "OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n"); | 307 "OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n"); |
305 } else { | 308 } else { |
306 // Special PNaCl support files, that are installed on the | 309 // Special PNaCl support files, that are installed on the |
307 // user machine. | 310 // user machine. |
308 int32_t fd = PnaclResources::GetPnaclFD( | 311 int32_t fd = PnaclResources::GetPnaclFD( |
309 plugin_, | 312 plugin_, |
310 PnaclUrls::PnaclComponentURLToFilename(mapped_url).c_str()); | 313 PnaclUrls::PnaclComponentURLToFilename(mapped_url).c_str()); |
311 if (fd < 0) { | 314 if (fd < 0) { |
312 // We should check earlier if the pnacl component wasn't installed | 315 // We should check earlier if the pnacl component wasn't installed |
313 // yet. At this point, we can't do much anymore, so just continue | 316 // yet. At this point, we can't do much anymore, so just continue |
314 // with an invalid fd. | 317 // with an invalid fd. |
315 NaClLog(4, | 318 NaClLog(4, |
316 "OpenManifestEntry_MainThreadContinuation: " | 319 "OpenManifestEntry_MainThreadContinuation: " |
317 "GetReadonlyPnaclFd failed\n"); | 320 "GetReadonlyPnaclFd failed\n"); |
318 // TODO(jvoung): Separate the error codes? | 321 // TODO(jvoung): Separate the error codes? |
319 p->error_info->SetReport(ERROR_MANIFEST_OPEN, | 322 p->error_info->SetReport(ERROR_MANIFEST_OPEN, |
320 "ServiceRuntime: GetPnaclFd failed"); | 323 "ServiceRuntime: GetPnaclFd failed"); |
321 } | 324 } |
322 nacl::MutexLocker take(&mu_); | 325 nacl::MutexLocker take(&mu_); |
323 *p->op_complete_ptr = true; // done! | 326 *p->op_complete_ptr = true; // done! |
324 *p->out_desc = fd; | 327 // TODO(ncbray): more info for faster validation? |
Mark Seaborn
2013/05/16 23:01:47
I'm not sure what this TODO means
Nick Bray (chromium)
2013/05/21 20:09:06
Done.
| |
328 p->file_info->desc = fd; | |
325 NaClXCondVarBroadcast(&cv_); | 329 NaClXCondVarBroadcast(&cv_); |
326 NaClLog(4, | 330 NaClLog(4, |
327 "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n"); | 331 "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n"); |
328 } | 332 } |
329 } else { | 333 } else { |
330 // Requires PNaCl translation. | 334 // Requires PNaCl translation. |
331 NaClLog(4, | 335 NaClLog(4, |
332 "OpenManifestEntry_MainThreadContinuation: " | 336 "OpenManifestEntry_MainThreadContinuation: " |
333 "pulling down and translating.\n"); | 337 "pulling down and translating.\n"); |
334 if (plugin_->nacl_interface()->IsPnaclEnabled()) { | 338 if (plugin_->nacl_interface()->IsPnaclEnabled()) { |
335 pp::CompletionCallback translate_callback = | 339 pp::CompletionCallback translate_callback = |
336 WeakRefNewCallback( | 340 WeakRefNewCallback( |
337 anchor_, | 341 anchor_, |
338 this, | 342 this, |
339 &PluginReverseInterface::BitcodeTranslate_MainThreadContinuation, | 343 &PluginReverseInterface::BitcodeTranslate_MainThreadContinuation, |
340 open_cont); | 344 open_cont); |
341 // Will always call the callback on success or failure. | 345 // Will always call the callback on success or failure. |
342 pnacl_coordinator_.reset( | 346 pnacl_coordinator_.reset( |
343 PnaclCoordinator::BitcodeToNative(plugin_, | 347 PnaclCoordinator::BitcodeToNative(plugin_, |
344 mapped_url, | 348 mapped_url, |
345 pnacl_options, | 349 pnacl_options, |
346 translate_callback)); | 350 translate_callback)); |
347 } else { | 351 } else { |
348 nacl::MutexLocker take(&mu_); | 352 nacl::MutexLocker take(&mu_); |
349 *p->op_complete_ptr = true; // done... | 353 *p->op_complete_ptr = true; // done... |
350 *p->out_desc = -1; // but failed. | 354 p->file_info->desc = -1; // but failed. |
351 p->error_info->SetReport(ERROR_PNACL_NOT_ENABLED, | 355 p->error_info->SetReport(ERROR_PNACL_NOT_ENABLED, |
352 "ServiceRuntime: GetPnaclFd failed -- pnacl not " | 356 "ServiceRuntime: GetPnaclFd failed -- pnacl not " |
353 "enabled with --enable-pnacl."); | 357 "enabled with --enable-pnacl."); |
354 NaClXCondVarBroadcast(&cv_); | 358 NaClXCondVarBroadcast(&cv_); |
355 return; | 359 return; |
356 } | 360 } |
357 } | 361 } |
358 // p is deleted automatically | 362 // p is deleted automatically |
359 } | 363 } |
360 | 364 |
361 void PluginReverseInterface::StreamAsFile_MainThreadContinuation( | 365 void PluginReverseInterface::StreamAsFile_MainThreadContinuation( |
362 OpenManifestEntryResource* p, | 366 OpenManifestEntryResource* p, |
363 int32_t result) { | 367 int32_t result) { |
364 NaClLog(4, | 368 NaClLog(4, |
365 "Entered StreamAsFile_MainThreadContinuation\n"); | 369 "Entered StreamAsFile_MainThreadContinuation\n"); |
366 | 370 |
367 nacl::MutexLocker take(&mu_); | 371 nacl::MutexLocker take(&mu_); |
368 if (result == PP_OK) { | 372 if (result == PP_OK) { |
369 NaClLog(4, "StreamAsFile_MainThreadContinuation: GetPOSIXFileDesc(%s)\n", | 373 NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n", |
370 p->url.c_str()); | 374 p->url.c_str()); |
371 *p->out_desc = plugin_->GetPOSIXFileDesc(p->url); | 375 *p->file_info = plugin_->GetFileInfo(p->url); |
376 | |
372 NaClLog(4, | 377 NaClLog(4, |
373 "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", | 378 "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n", |
374 *p->out_desc); | 379 p->file_info->desc); |
375 } else { | 380 } else { |
376 NaClLog(4, | 381 NaClLog(4, |
377 "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); | 382 "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n"); |
378 *p->out_desc = -1; | 383 p->file_info->desc = -1; |
379 p->error_info->SetReport(ERROR_MANIFEST_OPEN, | 384 p->error_info->SetReport(ERROR_MANIFEST_OPEN, |
380 "Plugin StreamAsFile failed at callback"); | 385 "Plugin StreamAsFile failed at callback"); |
381 } | 386 } |
382 *p->op_complete_ptr = true; | 387 *p->op_complete_ptr = true; |
383 NaClXCondVarBroadcast(&cv_); | 388 NaClXCondVarBroadcast(&cv_); |
384 } | 389 } |
385 | 390 |
386 | 391 |
387 void PluginReverseInterface::BitcodeTranslate_MainThreadContinuation( | 392 void PluginReverseInterface::BitcodeTranslate_MainThreadContinuation( |
388 OpenManifestEntryResource* p, | 393 OpenManifestEntryResource* p, |
389 int32_t result) { | 394 int32_t result) { |
390 NaClLog(4, | 395 NaClLog(4, |
391 "Entered BitcodeTranslate_MainThreadContinuation\n"); | 396 "Entered BitcodeTranslate_MainThreadContinuation\n"); |
392 | 397 |
393 nacl::MutexLocker take(&mu_); | 398 nacl::MutexLocker take(&mu_); |
394 if (result == PP_OK) { | 399 if (result == PP_OK) { |
395 // TODO(jvoung): clean this up. We are assuming that the NaClDesc is | 400 // TODO(jvoung): clean this up. We are assuming that the NaClDesc is |
396 // a host IO desc and doing a downcast. Once the ReverseInterface | 401 // a host IO desc and doing a downcast. Once the ReverseInterface |
397 // accepts NaClDescs we can avoid this downcast. | 402 // accepts NaClDescs we can avoid this downcast. |
398 NaClDesc* desc = pnacl_coordinator_->ReleaseTranslatedFD()->desc(); | 403 NaClDesc* desc = pnacl_coordinator_->ReleaseTranslatedFD()->desc(); |
399 struct NaClDescIoDesc* ndiodp = (struct NaClDescIoDesc*)desc; | 404 struct NaClDescIoDesc* ndiodp = (struct NaClDescIoDesc*)desc; |
400 *p->out_desc = ndiodp->hd->d; | 405 p->file_info->desc = ndiodp->hd->d; |
401 pnacl_coordinator_.reset(NULL); | 406 pnacl_coordinator_.reset(NULL); |
402 NaClLog(4, | 407 NaClLog(4, |
403 "BitcodeTranslate_MainThreadContinuation: PP_OK, desc %d\n", | 408 "BitcodeTranslate_MainThreadContinuation: PP_OK, desc %d\n", |
404 *p->out_desc); | 409 p->file_info->desc); |
405 } else { | 410 } else { |
406 NaClLog(4, | 411 NaClLog(4, |
407 "BitcodeTranslate_MainThreadContinuation: !PP_OK, " | 412 "BitcodeTranslate_MainThreadContinuation: !PP_OK, " |
408 "setting desc -1\n"); | 413 "setting desc -1\n"); |
409 *p->out_desc = -1; | 414 p->file_info->desc = -1; |
410 // Error should have been reported by pnacl coordinator. | 415 // Error should have been reported by pnacl coordinator. |
411 NaClLog(LOG_ERROR, "PluginReverseInterface::BitcodeTranslate error.\n"); | 416 NaClLog(LOG_ERROR, "PluginReverseInterface::BitcodeTranslate error.\n"); |
412 } | 417 } |
413 *p->op_complete_ptr = true; | 418 *p->op_complete_ptr = true; |
414 NaClXCondVarBroadcast(&cv_); | 419 NaClXCondVarBroadcast(&cv_); |
415 } | 420 } |
416 | 421 |
417 | 422 |
418 bool PluginReverseInterface::CloseManifestEntry(int32_t desc) { | 423 bool PluginReverseInterface::CloseManifestEntry(int32_t desc) { |
419 bool op_complete = false; | 424 bool op_complete = false; |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
846 | 851 |
847 nacl::string ServiceRuntime::GetCrashLogOutput() { | 852 nacl::string ServiceRuntime::GetCrashLogOutput() { |
848 if (NULL != subprocess_.get()) { | 853 if (NULL != subprocess_.get()) { |
849 return subprocess_->GetCrashLogOutput(); | 854 return subprocess_->GetCrashLogOutput(); |
850 } else { | 855 } else { |
851 return std::string(); | 856 return std::string(); |
852 } | 857 } |
853 } | 858 } |
854 | 859 |
855 } // namespace plugin | 860 } // namespace plugin |
OLD | NEW |