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