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 "native_client/src/trusted/plugin/pnacl_coordinator.h" | 5 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
| 10 #include "native_client/src/include/checked_cast.h" |
10 #include "native_client/src/include/portability_io.h" | 11 #include "native_client/src/include/portability_io.h" |
11 #include "native_client/src/shared/platform/nacl_check.h" | 12 #include "native_client/src/shared/platform/nacl_check.h" |
12 #include "native_client/src/trusted/plugin/local_temp_file.h" | 13 #include "native_client/src/trusted/plugin/local_temp_file.h" |
13 #include "native_client/src/trusted/plugin/manifest.h" | 14 #include "native_client/src/trusted/plugin/manifest.h" |
14 #include "native_client/src/trusted/plugin/plugin.h" | 15 #include "native_client/src/trusted/plugin/plugin.h" |
15 #include "native_client/src/trusted/plugin/plugin_error.h" | 16 #include "native_client/src/trusted/plugin/plugin_error.h" |
16 #include "native_client/src/trusted/plugin/pnacl_translate_thread.h" | 17 #include "native_client/src/trusted/plugin/pnacl_translate_thread.h" |
17 #include "native_client/src/trusted/plugin/service_runtime.h" | 18 #include "native_client/src/trusted/plugin/service_runtime.h" |
18 #include "native_client/src/trusted/plugin/temporary_file.h" | 19 #include "native_client/src/trusted/plugin/temporary_file.h" |
19 #include "native_client/src/trusted/service_runtime/include/sys/stat.h" | |
20 | 20 |
| 21 #include "ppapi/c/pp_bool.h" |
21 #include "ppapi/c/pp_errors.h" | 22 #include "ppapi/c/pp_errors.h" |
22 #include "ppapi/c/ppb_file_io.h" | 23 #include "ppapi/c/ppb_file_io.h" |
23 #include "ppapi/cpp/file_io.h" | 24 #include "ppapi/cpp/file_io.h" |
24 | 25 |
25 namespace { | 26 namespace { |
26 const char kPnaclTempDir[] = "/.pnacl"; | 27 const char kPnaclTempDir[] = "/.pnacl"; |
| 28 const uint32_t kCopyBufSize = 512 << 10; |
27 } | 29 } |
28 | 30 |
29 namespace plugin { | 31 namespace plugin { |
30 | 32 |
31 ////////////////////////////////////////////////////////////////////// | 33 ////////////////////////////////////////////////////////////////////// |
32 // Pnacl-specific manifest support. | 34 // Pnacl-specific manifest support. |
33 ////////////////////////////////////////////////////////////////////// | 35 ////////////////////////////////////////////////////////////////////// |
34 class ExtensionManifest : public Manifest { | 36 class ExtensionManifest : public Manifest { |
35 public: | 37 public: |
36 explicit ExtensionManifest(const pp::URLUtil_Dev* url_util) | 38 explicit ExtensionManifest(const pp::URLUtil_Dev* url_util) |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( | 177 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( |
176 Plugin* plugin, | 178 Plugin* plugin, |
177 const nacl::string& pexe_url, | 179 const nacl::string& pexe_url, |
178 const nacl::string& cache_identity, | 180 const nacl::string& cache_identity, |
179 const pp::CompletionCallback& translate_notify_callback) { | 181 const pp::CompletionCallback& translate_notify_callback) { |
180 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", | 182 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", |
181 static_cast<void*>(plugin), pexe_url.c_str())); | 183 static_cast<void*>(plugin), pexe_url.c_str())); |
182 PnaclCoordinator* coordinator = | 184 PnaclCoordinator* coordinator = |
183 new PnaclCoordinator(plugin, pexe_url, | 185 new PnaclCoordinator(plugin, pexe_url, |
184 cache_identity, translate_notify_callback); | 186 cache_identity, translate_notify_callback); |
185 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p)\n", | 187 coordinator->off_the_record_ = |
186 reinterpret_cast<const void*>(coordinator->manifest_.get()))); | 188 plugin->nacl_interface()->IsOffTheRecord(); |
| 189 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, " |
| 190 "off_the_record=%b)\n", |
| 191 reinterpret_cast<const void*>(coordinator->manifest_.get()), |
| 192 coordinator->off_the_record_)); |
| 193 |
187 // Load llc and ld. | 194 // Load llc and ld. |
188 std::vector<nacl::string> resource_urls; | 195 std::vector<nacl::string> resource_urls; |
189 resource_urls.push_back(PnaclUrls::GetLlcUrl()); | 196 resource_urls.push_back(PnaclUrls::GetLlcUrl()); |
190 resource_urls.push_back(PnaclUrls::GetLdUrl()); | 197 resource_urls.push_back(PnaclUrls::GetLdUrl()); |
191 pp::CompletionCallback resources_cb = | 198 pp::CompletionCallback resources_cb = |
192 coordinator->callback_factory_.NewCallback( | 199 coordinator->callback_factory_.NewCallback( |
193 &PnaclCoordinator::ResourcesDidLoad); | 200 &PnaclCoordinator::ResourcesDidLoad); |
194 coordinator->resources_.reset( | 201 coordinator->resources_.reset( |
195 new PnaclResources(plugin, | 202 new PnaclResources(plugin, |
196 coordinator, | 203 coordinator, |
(...skipping 30 matching lines...) Expand all Loading... |
227 const nacl::string& pexe_url, | 234 const nacl::string& pexe_url, |
228 const nacl::string& cache_identity, | 235 const nacl::string& cache_identity, |
229 const pp::CompletionCallback& translate_notify_callback) | 236 const pp::CompletionCallback& translate_notify_callback) |
230 : translate_finish_error_(PP_OK), | 237 : translate_finish_error_(PP_OK), |
231 plugin_(plugin), | 238 plugin_(plugin), |
232 translate_notify_callback_(translate_notify_callback), | 239 translate_notify_callback_(translate_notify_callback), |
233 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), | 240 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), |
234 manifest_(new ExtensionManifest(plugin->url_util())), | 241 manifest_(new ExtensionManifest(plugin->url_util())), |
235 pexe_url_(pexe_url), | 242 pexe_url_(pexe_url), |
236 cache_identity_(cache_identity), | 243 cache_identity_(cache_identity), |
237 error_already_reported_(false) { | 244 error_already_reported_(false), |
| 245 off_the_record_(false) { |
238 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", | 246 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", |
239 static_cast<void*>(this), static_cast<void*>(plugin))); | 247 static_cast<void*>(this), static_cast<void*>(plugin))); |
240 callback_factory_.Initialize(this); | 248 callback_factory_.Initialize(this); |
241 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get())); | 249 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get())); |
242 } | 250 } |
243 | 251 |
244 PnaclCoordinator::~PnaclCoordinator() { | 252 PnaclCoordinator::~PnaclCoordinator() { |
245 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, " | 253 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, " |
246 "translate_thread=%p\n", | 254 "translate_thread=%p\n", |
247 static_cast<void*>(this), translate_thread_.get())); | 255 static_cast<void*>(this), translate_thread_.get())); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 } else { | 295 } else { |
288 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpapiError an earlier error was " | 296 PLUGIN_PRINTF(("PnaclCoordinator::ReportPpapiError an earlier error was " |
289 "already reported -- Skipping.\n")); | 297 "already reported -- Skipping.\n")); |
290 } | 298 } |
291 } | 299 } |
292 | 300 |
293 // Signal that Pnacl translation completed normally. | 301 // Signal that Pnacl translation completed normally. |
294 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { | 302 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { |
295 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" | 303 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" |
296 NACL_PRId32")\n", pp_error)); | 304 NACL_PRId32")\n", pp_error)); |
297 // Save the translate error code, and inspect after cleaning up junk files. | 305 // Bail out if there was an earlier error (e.g., pexe load failure). |
298 // Note: If there was a surfaway and the file objects were actually | 306 if (translate_finish_error_ != PP_OK) { |
299 // destroyed, then we are in trouble since the obj_file_, nexe_file_, | 307 ReportPpapiError(translate_finish_error_); |
300 // etc. may have been destroyed. | 308 return; |
301 // TODO(jvoung,sehr): Fix. | |
302 // If there was an error already set (e.g. pexe load failure) then we want | |
303 // to use the first one, (which might be something useful) rather than | |
304 // the one from the compiler, (which is always just PP_ERROR_FAILED) | |
305 if (translate_finish_error_ == PP_OK) translate_finish_error_ = pp_error; | |
306 | |
307 // Close the nexe temporary file. | |
308 if (nexe_file_ != NULL) { | |
309 pp::CompletionCallback cb = | |
310 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasClosed); | |
311 nexe_file_->Close(cb); | |
312 } | 309 } |
313 } | 310 // Bail out if there is an error from the translation thread. |
314 | |
315 void PnaclCoordinator::NexeFileWasClosed(int32_t pp_error) { | |
316 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasClosed (pp_error=%" | |
317 NACL_PRId32")\n", pp_error)); | |
318 if (pp_error != PP_OK) { | 311 if (pp_error != PP_OK) { |
319 ReportPpapiError(pp_error); | 312 ReportPpapiError(pp_error); |
320 return; | 313 return; |
321 } | 314 } |
322 // Now that cleanup of the obj file is done, check the old TranslateFinished | 315 |
323 // error code to see if we should proceed normally or not. | 316 // The nexe is written to the temp_nexe_file_. We must Reset() the file |
324 if (translate_finish_error_ != PP_OK) { | 317 // pointer to be able to read it again from the beginning. |
325 pp::CompletionCallback cb = | 318 temp_nexe_file_->Reset(); |
326 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasDeleted); | 319 |
327 nexe_file_->Delete(cb); | 320 if (cache_identity_ != "" && cached_nexe_file_ != NULL) { |
| 321 // We are using a cache, but had a cache miss, which is why we did the |
| 322 // translation. Reset cached_nexe_file_ to have a random name, |
| 323 // for scratch purposes, before renaming to the final cache_identity_. |
| 324 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), |
| 325 nacl::string(kPnaclTempDir))); |
| 326 pp::CompletionCallback cb = callback_factory_.NewCallback( |
| 327 &PnaclCoordinator::CachedNexeOpenedForWrite); |
| 328 cached_nexe_file_->OpenWrite(cb); |
| 329 } else { |
| 330 // For now, tolerate bitcode that is missing a cache identity, and |
| 331 // tolerate the lack of caching in incognito mode. |
| 332 PLUGIN_PRINTF(("PnaclCoordinator -- not caching.\n")); |
| 333 NexeReadDidOpen(PP_OK); |
| 334 } |
| 335 } |
| 336 |
| 337 void PnaclCoordinator::CachedNexeOpenedForWrite(int32_t pp_error) { |
| 338 if (pp_error != PP_OK) { |
| 339 ReportPpapiError(pp_error, "Failed to open cache file for write."); |
328 return; | 340 return; |
329 } | 341 } |
330 | 342 |
331 // Rename the nexe file to the cache id. | 343 // Copy the contents from temp_nexe_file_ -> cached_nexe_file_, |
332 if (cache_identity_ != "") { | 344 // then rename the cached_nexe_file_ file to the cache id. |
333 pp::CompletionCallback cb = | 345 int64_t cur_offset = 0; |
334 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); | 346 nacl::DescWrapper* read_wrapper = temp_nexe_file_->read_wrapper(); |
335 nexe_file_->Rename(cache_identity_, cb); | 347 char buf[kCopyBufSize]; |
336 } else { | 348 int32_t num_read = |
337 // For now tolerate bitcode that is missing a cache identity. | 349 nacl::assert_cast<int32_t>(read_wrapper->Read(buf, sizeof buf)); |
338 PLUGIN_PRINTF(("PnaclCoordinator -- WARNING: missing cache identity," | 350 // Hit EOF or something. |
339 " not caching.\n")); | 351 if (num_read == 0) { |
340 NexeFileWasRenamed(PP_OK); | 352 NexeWasCopiedToCache(PP_OK); |
| 353 return; |
341 } | 354 } |
| 355 if (num_read < 0) { |
| 356 PLUGIN_PRINTF(("PnaclCoordinator::CachedNexeOpenedForWrite read failed " |
| 357 "(error=%"NACL_PRId32")\n", num_read)); |
| 358 NexeWasCopiedToCache(PP_ERROR_FAILED); |
| 359 return; |
| 360 } |
| 361 pp::CompletionCallback cb = callback_factory_.NewCallback( |
| 362 &PnaclCoordinator::DidCopyNexeToCachePartial, num_read, cur_offset); |
| 363 cached_nexe_file_->write_file_io()->Write(cur_offset, buf, num_read, cb); |
| 364 } |
| 365 |
| 366 void PnaclCoordinator::DidCopyNexeToCachePartial(int32_t pp_error, |
| 367 int32_t num_read_prev, |
| 368 int64_t cur_offset) { |
| 369 PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial " |
| 370 "(pp_error=%"NACL_PRId32", num_read_prev=%"NACL_PRId32"" |
| 371 ", cur_offset=%"NACL_PRId64").\n", |
| 372 pp_error, num_read_prev, cur_offset)); |
| 373 // Assume we are done. |
| 374 if (pp_error == PP_OK) { |
| 375 NexeWasCopiedToCache(PP_OK); |
| 376 return; |
| 377 } |
| 378 if (pp_error < PP_OK) { |
| 379 PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial failed (err=%" |
| 380 NACL_PRId32")\n", pp_error)); |
| 381 NexeWasCopiedToCache(pp_error); |
| 382 return; |
| 383 } |
| 384 |
| 385 // Check if we wrote as much as we read. |
| 386 nacl::DescWrapper* read_wrapper = temp_nexe_file_->read_wrapper(); |
| 387 if (pp_error != num_read_prev) { |
| 388 PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial partial " |
| 389 "write (bytes_written=%"NACL_PRId32" vs " |
| 390 "read=%"NACL_PRId32")\n", pp_error, num_read_prev)); |
| 391 CHECK(pp_error < num_read_prev); |
| 392 // Seek back to re-read the bytes that were not written. |
| 393 nacl_off64_t seek_result = |
| 394 read_wrapper->Seek(pp_error - num_read_prev, SEEK_CUR); |
| 395 if (seek_result < 0) { |
| 396 PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial seek failed " |
| 397 "(err=%"NACL_PRId64")\n", seek_result)); |
| 398 NexeWasCopiedToCache(PP_ERROR_FAILED); |
| 399 return; |
| 400 } |
| 401 } |
| 402 |
| 403 int64_t next_offset = cur_offset + pp_error; |
| 404 char buf[kCopyBufSize]; |
| 405 int32_t num_read = |
| 406 nacl::assert_cast<int32_t>(read_wrapper->Read(buf, sizeof buf)); |
| 407 PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial read (bytes=%" |
| 408 NACL_PRId32")\n", num_read)); |
| 409 // Hit EOF or something. |
| 410 if (num_read == 0) { |
| 411 NexeWasCopiedToCache(PP_OK); |
| 412 return; |
| 413 } |
| 414 if (num_read < 0) { |
| 415 PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial read failed " |
| 416 "(error=%"NACL_PRId32")\n", num_read)); |
| 417 NexeWasCopiedToCache(PP_ERROR_FAILED); |
| 418 return; |
| 419 } |
| 420 pp::CompletionCallback cb = callback_factory_.NewCallback( |
| 421 &PnaclCoordinator::DidCopyNexeToCachePartial, num_read, next_offset); |
| 422 PLUGIN_PRINTF(("PnaclCoordinator::CopyNexeToCache Writing (" |
| 423 "bytes=%"NACL_PRId32", buf=%p, file_io=%p)\n", num_read, buf, |
| 424 cached_nexe_file_->write_file_io())); |
| 425 cached_nexe_file_->write_file_io()->Write(next_offset, buf, num_read, cb); |
| 426 } |
| 427 |
| 428 void PnaclCoordinator::NexeWasCopiedToCache(int32_t pp_error) { |
| 429 if (pp_error != PP_OK) { |
| 430 // TODO(jvoung): This should probably try to delete the cache file |
| 431 // before returning... |
| 432 ReportPpapiError(pp_error, "Failed to copy nexe to cache."); |
| 433 return; |
| 434 } |
| 435 // Rename the cached_nexe_file_ file to the cache id, to finalize. |
| 436 pp::CompletionCallback cb = |
| 437 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); |
| 438 cached_nexe_file_->Rename(cache_identity_, cb); |
342 } | 439 } |
343 | 440 |
344 void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { | 441 void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { |
345 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasRenamed (pp_error=%" | 442 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasRenamed (pp_error=%" |
346 NACL_PRId32")\n", pp_error)); | 443 NACL_PRId32")\n", pp_error)); |
347 // NOTE: if the file already existed, it looks like the rename will | 444 // NOTE: if the file already existed, it looks like the rename will |
348 // happily succeed. However, we should add a test for this. | 445 // happily succeed. However, we should add a test for this. |
349 if (pp_error != PP_OK) { | 446 if (pp_error != PP_OK) { |
350 ReportPpapiError(pp_error, "Failed to place cached bitcode translation."); | 447 ReportPpapiError(pp_error, "Failed to place cached bitcode translation."); |
351 return; | 448 return; |
352 } | 449 } |
353 nexe_file_->FinishRename(); | 450 |
354 // Open the nexe temporary file for reading. | 451 cached_nexe_file_->FinishRename(); |
| 452 // Open the cache file for reading. |
355 pp::CompletionCallback cb = | 453 pp::CompletionCallback cb = |
356 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); | 454 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); |
357 nexe_file_->OpenRead(cb); | 455 cached_nexe_file_->OpenRead(cb); |
358 } | 456 } |
359 | 457 |
360 void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { | 458 void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { |
361 PLUGIN_PRINTF(("PnaclCoordinator::NexeReadDidOpen (pp_error=%" | 459 PLUGIN_PRINTF(("PnaclCoordinator::NexeReadDidOpen (pp_error=%" |
362 NACL_PRId32")\n", pp_error)); | 460 NACL_PRId32")\n", pp_error)); |
363 if (pp_error != PP_OK) { | 461 if (pp_error != PP_OK) { |
364 ReportPpapiError(pp_error, "Failed to open translated nexe."); | 462 ReportPpapiError(pp_error, "Failed to open translated nexe."); |
365 return; | 463 return; |
366 } | 464 } |
367 // Transfer ownership of the nexe wrapper to the coordinator. | 465 |
368 translated_fd_.reset(nexe_file_->release_read_wrapper()); | 466 // Transfer ownership of cache/temp file's wrapper to the coordinator. |
| 467 if (cached_nexe_file_ != NULL) { |
| 468 translated_fd_.reset(cached_nexe_file_->release_read_wrapper()); |
| 469 } else { |
| 470 translated_fd_.reset(temp_nexe_file_->release_read_wrapper()); |
| 471 } |
369 plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); | 472 plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); |
370 translate_notify_callback_.Run(pp_error); | 473 translate_notify_callback_.Run(pp_error); |
371 } | 474 } |
372 | 475 |
373 void PnaclCoordinator::NexeFileWasDeleted(int32_t pp_error) { | |
374 PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasDeleted (pp_error=%" | |
375 NACL_PRId32")\n", pp_error)); | |
376 ReportPpapiError(translate_finish_error_); | |
377 } | |
378 | |
379 void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { | 476 void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { |
380 PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" | 477 PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" |
381 NACL_PRId32")\n", pp_error)); | 478 NACL_PRId32")\n", pp_error)); |
382 if (pp_error != PP_OK) { | 479 if (pp_error != PP_OK) { |
383 ReportPpapiError(pp_error, "resources failed to load."); | 480 ReportPpapiError(pp_error, "resources failed to load."); |
384 return; | 481 return; |
385 } | 482 } |
386 // Open the local temporary file system to create the temporary files | 483 |
387 // for the object and nexe. | 484 if (!off_the_record_) { |
388 pp::CompletionCallback cb = | 485 // Open the local temporary FS to see if we get a hit in the cache. |
389 callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen); | 486 pp::CompletionCallback cb = |
390 if (!file_system_->Open(0, cb)) { | 487 callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen); |
391 ReportNonPpapiError("failed to open file system."); | 488 if (!file_system_->Open(0, cb)) { |
| 489 ReportNonPpapiError("failed to open file system."); |
| 490 } |
| 491 } else { |
| 492 // We don't have a cache, so do the non-cached codepath. |
| 493 CachedFileDidOpen(PP_ERROR_FAILED); |
392 } | 494 } |
393 } | 495 } |
394 | 496 |
395 void PnaclCoordinator::FileSystemDidOpen(int32_t pp_error) { | 497 void PnaclCoordinator::FileSystemDidOpen(int32_t pp_error) { |
396 PLUGIN_PRINTF(("PnaclCoordinator::FileSystemDidOpen (pp_error=%" | 498 PLUGIN_PRINTF(("PnaclCoordinator::FileSystemDidOpen (pp_error=%" |
397 NACL_PRId32")\n", pp_error)); | 499 NACL_PRId32")\n", pp_error)); |
398 if (pp_error != PP_OK) { | 500 if (pp_error != PP_OK) { |
399 ReportPpapiError(pp_error, "file system didn't open."); | 501 ReportPpapiError(pp_error, "file system didn't open."); |
400 return; | 502 return; |
401 } | 503 } |
402 dir_ref_.reset(new pp::FileRef(*file_system_, | 504 dir_ref_.reset(new pp::FileRef(*file_system_, kPnaclTempDir)); |
403 kPnaclTempDir)); | |
404 // Attempt to create the directory. | 505 // Attempt to create the directory. |
405 pp::CompletionCallback cb = | 506 pp::CompletionCallback cb = |
406 callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated); | 507 callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated); |
407 dir_ref_->MakeDirectory(cb); | 508 dir_ref_->MakeDirectory(cb); |
408 } | 509 } |
409 | 510 |
410 void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { | 511 void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { |
411 PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasCreated (pp_error=%" | 512 PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasCreated (pp_error=%" |
412 NACL_PRId32")\n", pp_error)); | 513 NACL_PRId32")\n", pp_error)); |
413 if (pp_error != PP_ERROR_FILEEXISTS && pp_error != PP_OK) { | 514 if (pp_error != PP_ERROR_FILEEXISTS && pp_error != PP_OK) { |
414 // Directory did not exist and could not be created. | 515 // Directory did not exist and could not be created. |
415 ReportPpapiError(pp_error, "directory creation/check failed."); | 516 ReportPpapiError(pp_error, "directory creation/check failed."); |
416 return; | 517 return; |
417 } | 518 } |
418 if (cache_identity_ != "") { | 519 if (cache_identity_ != "") { |
419 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), | 520 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), |
420 nacl::string(kPnaclTempDir), | 521 nacl::string(kPnaclTempDir), |
421 cache_identity_)); | 522 cache_identity_)); |
422 pp::CompletionCallback cb = | 523 pp::CompletionCallback cb = |
423 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); | 524 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); |
424 nexe_file_->OpenRead(cb); | 525 cached_nexe_file_->OpenRead(cb); |
425 } else { | 526 } else { |
426 // For now, tolerate lack of cache identity... | 527 // For now, tolerate lack of cache identity... |
427 CachedFileDidOpen(PP_ERROR_FAILED); | 528 CachedFileDidOpen(PP_ERROR_FAILED); |
428 } | 529 } |
429 } | 530 } |
430 | 531 |
431 void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { | 532 void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { |
432 PLUGIN_PRINTF(("PnaclCoordinator::CachedFileDidOpen (pp_error=%" | 533 PLUGIN_PRINTF(("PnaclCoordinator::CachedFileDidOpen (pp_error=%" |
433 NACL_PRId32")\n", pp_error)); | 534 NACL_PRId32")\n", pp_error)); |
434 if (pp_error == PP_OK) { | 535 if (pp_error == PP_OK) { |
(...skipping 25 matching lines...) Expand all Loading... |
460 // TODO(dschuff): need to use url_util_->ResolveRelativeToURL? | 561 // TODO(dschuff): need to use url_util_->ResolveRelativeToURL? |
461 if (!streaming_downloader_->OpenStream(pexe_url_, cb, this)) { | 562 if (!streaming_downloader_->OpenStream(pexe_url_, cb, this)) { |
462 ReportNonPpapiError(nacl::string("failed to open stream ") + pexe_url_); | 563 ReportNonPpapiError(nacl::string("failed to open stream ") + pexe_url_); |
463 } | 564 } |
464 } | 565 } |
465 | 566 |
466 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { | 567 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { |
467 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" | 568 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" |
468 NACL_PRId32")\n", pp_error)); | 569 NACL_PRId32")\n", pp_error)); |
469 if (pp_error != PP_OK) { | 570 if (pp_error != PP_OK) { |
470 // Defer reporting the error and obj_file/nexe_file cleanup until after | 571 // Defer reporting the error and cleanup until after the translation |
471 // the translation thread returns, because it may be accessing the | 572 // thread returns, because it may be accessing the coordinator's |
472 // coordinator's objects or writing to the files. | 573 // objects or writing to the files. |
473 translate_finish_error_ = pp_error; | 574 translate_finish_error_ = pp_error; |
474 error_info_.SetReport(ERROR_UNKNOWN, | 575 error_info_.SetReport(ERROR_UNKNOWN, |
475 nacl::string("PnaclCoordinator: pexe load failed.")); | 576 nacl::string("PnaclCoordinator: pexe load failed.")); |
476 translate_thread_->AbortSubprocesses(); | 577 translate_thread_->AbortSubprocesses(); |
477 } | 578 } |
478 } | 579 } |
479 | 580 |
480 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, | 581 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, |
481 FileStreamData data) { | 582 FileStreamData data) { |
482 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" | 583 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" |
483 NACL_PRId32", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); | 584 NACL_PRId32", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); |
484 DCHECK(translate_thread_.get()); | 585 DCHECK(translate_thread_.get()); |
485 translate_thread_->PutBytes(data, pp_error); | 586 translate_thread_->PutBytes(data, pp_error); |
486 } | 587 } |
487 | 588 |
488 StreamCallback PnaclCoordinator::GetCallback() { | 589 StreamCallback PnaclCoordinator::GetCallback() { |
489 return callback_factory_.NewCallbackWithOutput( | 590 return callback_factory_.NewCallbackWithOutput( |
490 &PnaclCoordinator::BitcodeStreamGotData); | 591 &PnaclCoordinator::BitcodeStreamGotData); |
491 } | 592 } |
492 | 593 |
493 void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { | 594 void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { |
494 PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileDidOpen (pp_error=%" | 595 PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileDidOpen (pp_error=%" |
495 NACL_PRId32")\n", pp_error)); | 596 NACL_PRId32")\n", pp_error)); |
496 if (pp_error != PP_OK) { | 597 if (pp_error != PP_OK) { |
497 ReportPpapiError(pp_error); | 598 ReportPpapiError(pp_error); |
498 return; | 599 return; |
499 } | 600 } |
500 // Create the nexe file for connecting ld and sel_ldr. | 601 // Create the nexe file for connecting ld and sel_ldr. |
501 // Start translation when done with this last step of setup! | 602 // Start translation when done with this last step of setup! |
502 nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), | 603 temp_nexe_file_.reset(new TempFile(plugin_)); |
503 nacl::string(kPnaclTempDir))); | |
504 pp::CompletionCallback cb = | 604 pp::CompletionCallback cb = |
505 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); | 605 callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); |
506 nexe_file_->OpenWrite(cb); | 606 temp_nexe_file_->Open(cb); |
507 } | 607 } |
508 | 608 |
509 void PnaclCoordinator::RunTranslate(int32_t pp_error) { | 609 void PnaclCoordinator::RunTranslate(int32_t pp_error) { |
510 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" | 610 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" |
511 NACL_PRId32")\n", pp_error)); | 611 NACL_PRId32")\n", pp_error)); |
512 // Invoke llc followed by ld off the main thread. This allows use of | 612 // Invoke llc followed by ld off the main thread. This allows use of |
513 // blocking RPCs that would otherwise block the JavaScript main thread. | 613 // blocking RPCs that would otherwise block the JavaScript main thread. |
514 pp::CompletionCallback report_translate_finished = | 614 pp::CompletionCallback report_translate_finished = |
515 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); | 615 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); |
516 | 616 |
517 CHECK(translate_thread_ != NULL); | 617 CHECK(translate_thread_ != NULL); |
518 translate_thread_->RunTranslate(report_translate_finished, | 618 translate_thread_->RunTranslate(report_translate_finished, |
519 manifest_.get(), | 619 manifest_.get(), |
520 ld_manifest_.get(), | 620 ld_manifest_.get(), |
521 obj_file_.get(), | 621 obj_file_.get(), |
522 nexe_file_.get(), | 622 temp_nexe_file_.get(), |
523 &error_info_, | 623 &error_info_, |
524 resources_.get(), | 624 resources_.get(), |
525 plugin_); | 625 plugin_); |
526 } | 626 } |
527 | 627 |
528 } // namespace plugin | 628 } // namespace plugin |
OLD | NEW |