| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/nacl/browser/pnacl_host.h" | 5 #include "components/nacl/browser/pnacl_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/task_runner_util.h" | 12 #include "base/task_runner_util.h" |
| 13 #include "base/threading/sequenced_worker_pool.h" | 13 #include "base/threading/sequenced_worker_pool.h" |
| 14 #include "components/nacl/browser/nacl_browser.h" | 14 #include "components/nacl/browser/nacl_browser.h" |
| 15 #include "components/nacl/browser/pnacl_translation_cache.h" | 15 #include "components/nacl/browser/pnacl_translation_cache.h" |
| 16 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 17 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 | 19 |
| 20 using content::BrowserThread; | 20 using content::BrowserThread; |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 static const base::FilePath::CharType kTranslationCacheDirectoryName[] = | 24 static const base::FilePath::CharType kTranslationCacheDirectoryName[] = |
| 25 FILE_PATH_LITERAL("PnaclTranslationCache"); | 25 FILE_PATH_LITERAL("PnaclTranslationCache"); |
| 26 // Delay to wait for initialization of the cache backend | 26 // Delay to wait for initialization of the cache backend |
| 27 static const int kTranslationCacheInitializationDelayMs = 20; | 27 static const int kTranslationCacheInitializationDelayMs = 20; |
| 28 | 28 |
| 29 void CloseBaseFile(base::File file) { | 29 void CloseBaseFile(base::File auto_file_closer) { |
| 30 // Not really needed because the file will go out of scope here. | |
| 31 file.Close(); | |
| 32 } | 30 } |
| 33 | 31 |
| 32 void CloseScopedFile(scoped_ptr<base::File> auto_file_closer) { |
| 34 } | 33 } |
| 35 | 34 |
| 35 } // namespace |
| 36 |
| 36 namespace pnacl { | 37 namespace pnacl { |
| 37 | 38 |
| 39 class FileProxy { |
| 40 public: |
| 41 FileProxy(scoped_ptr<base::File> file, base::WeakPtr<pnacl::PnaclHost> host); |
| 42 int Write(scoped_refptr<net::DrainableIOBuffer> buffer); |
| 43 void WriteDone(const PnaclHost::TranslationID& id, int result); |
| 44 |
| 45 private: |
| 46 scoped_ptr<base::File> file_; |
| 47 base::WeakPtr<pnacl::PnaclHost> host_; |
| 48 }; |
| 49 |
| 50 FileProxy::FileProxy(scoped_ptr<base::File> file, |
| 51 base::WeakPtr<pnacl::PnaclHost> host) |
| 52 : file_(file.Pass()), |
| 53 host_(host) { |
| 54 } |
| 55 |
| 56 int FileProxy::Write(scoped_refptr<net::DrainableIOBuffer> buffer) { |
| 57 int rv = file_->Write(0, buffer->data(), buffer->size()); |
| 58 if (rv == -1) |
| 59 PLOG(ERROR) << "FileProxy::Write error"; |
| 60 return rv; |
| 61 } |
| 62 |
| 63 void FileProxy::WriteDone(const PnaclHost::TranslationID& id, int result) { |
| 64 if (host_) { |
| 65 host_->OnBufferCopiedToTempFile(id, file_.Pass(), result); |
| 66 } else { |
| 67 BrowserThread::PostBlockingPoolTask( |
| 68 FROM_HERE, |
| 69 base::Bind(CloseScopedFile, Passed(&file_))); |
| 70 } |
| 71 } |
| 72 |
| 38 PnaclHost::PnaclHost() | 73 PnaclHost::PnaclHost() |
| 39 : pending_backend_operations_(0), | 74 : pending_backend_operations_(0), |
| 40 cache_state_(CacheUninitialized), | 75 cache_state_(CacheUninitialized), |
| 41 weak_factory_(this) {} | 76 weak_factory_(this) {} |
| 42 | 77 |
| 43 PnaclHost::~PnaclHost() { | 78 PnaclHost::~PnaclHost() { |
| 44 // When PnaclHost is destroyed, it's too late to post anything to the cache | 79 // When PnaclHost is destroyed, it's too late to post anything to the cache |
| 45 // thread (it will hang shutdown). So just leak the cache backend. | 80 // thread (it will hang shutdown). So just leak the cache backend. |
| 46 pnacl::PnaclTranslationCache* cache = disk_cache_.release(); | 81 pnacl::PnaclTranslationCache* cache = disk_cache_.release(); |
| 47 (void)cache; | 82 (void)cache; |
| 48 } | 83 } |
| 49 | 84 |
| 50 PnaclHost* PnaclHost::GetInstance() { return Singleton<PnaclHost>::get(); } | 85 PnaclHost* PnaclHost::GetInstance() { |
| 86 return Singleton<PnaclHost>::get(); |
| 87 } |
| 51 | 88 |
| 52 PnaclHost::PendingTranslation::PendingTranslation() | 89 PnaclHost::PendingTranslation::PendingTranslation() |
| 53 : process_handle(base::kNullProcessHandle), | 90 : process_handle(base::kNullProcessHandle), |
| 54 render_view_id(0), | 91 render_view_id(0), |
| 55 nexe_fd(base::kInvalidPlatformFileValue), | 92 nexe_fd(NULL), |
| 56 got_nexe_fd(false), | 93 got_nexe_fd(false), |
| 57 got_cache_reply(false), | 94 got_cache_reply(false), |
| 58 got_cache_hit(false), | 95 got_cache_hit(false), |
| 59 is_incognito(false), | 96 is_incognito(false), |
| 60 callback(NexeFdCallback()), | 97 callback(NexeFdCallback()), |
| 61 cache_info(nacl::PnaclCacheInfo()) {} | 98 cache_info(nacl::PnaclCacheInfo()) { |
| 62 PnaclHost::PendingTranslation::~PendingTranslation() {} | 99 } |
| 100 |
| 101 PnaclHost::PendingTranslation::~PendingTranslation() { |
| 102 if (nexe_fd) |
| 103 delete nexe_fd; |
| 104 } |
| 63 | 105 |
| 64 bool PnaclHost::TranslationMayBeCached( | 106 bool PnaclHost::TranslationMayBeCached( |
| 65 const PendingTranslationMap::iterator& entry) { | 107 const PendingTranslationMap::iterator& entry) { |
| 66 return !entry->second.is_incognito && | 108 return !entry->second.is_incognito && |
| 67 !entry->second.cache_info.has_no_store_header; | 109 !entry->second.cache_info.has_no_store_header; |
| 68 } | 110 } |
| 69 | 111 |
| 70 /////////////////////////////////////// Initialization | 112 /////////////////////////////////////// Initialization |
| 71 | 113 |
| 72 static base::FilePath GetCachePath() { | 114 static base::FilePath GetCachePath() { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 PendingTranslationMap::iterator entry = pending_translations_.find(id); | 254 PendingTranslationMap::iterator entry = pending_translations_.find(id); |
| 213 if (entry != pending_translations_.end()) { | 255 if (entry != pending_translations_.end()) { |
| 214 // Existing translation must have been abandonded. Clean it up. | 256 // Existing translation must have been abandonded. Clean it up. |
| 215 LOG(ERROR) << "GetNexeFd for already-pending translation"; | 257 LOG(ERROR) << "GetNexeFd for already-pending translation"; |
| 216 pending_translations_.erase(entry); | 258 pending_translations_.erase(entry); |
| 217 } | 259 } |
| 218 | 260 |
| 219 std::string cache_key(disk_cache_->GetKey(cache_info)); | 261 std::string cache_key(disk_cache_->GetKey(cache_info)); |
| 220 if (cache_key.empty()) { | 262 if (cache_key.empty()) { |
| 221 LOG(ERROR) << "GetNexeFd: Invalid cache info"; | 263 LOG(ERROR) << "GetNexeFd: Invalid cache info"; |
| 222 cb.Run(base::kInvalidPlatformFileValue, false); | 264 cb.Run(base::File(), false); |
| 223 return; | 265 return; |
| 224 } | 266 } |
| 225 | 267 |
| 226 PendingTranslation pt; | 268 PendingTranslation pt; |
| 227 pt.render_view_id = render_view_id; | 269 pt.render_view_id = render_view_id; |
| 228 pt.callback = cb; | 270 pt.callback = cb; |
| 229 pt.cache_info = cache_info; | 271 pt.cache_info = cache_info; |
| 230 pt.cache_key = cache_key; | 272 pt.cache_key = cache_key; |
| 231 pt.is_incognito = is_incognito; | 273 pt.is_incognito = is_incognito; |
| 232 pending_translations_[id] = pt; | 274 pending_translations_[id] = pt; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 LOG(ERROR) << "OnTempFileReturn: id not found"; | 331 LOG(ERROR) << "OnTempFileReturn: id not found"; |
| 290 BrowserThread::PostBlockingPoolTask( | 332 BrowserThread::PostBlockingPoolTask( |
| 291 FROM_HERE, base::Bind(CloseBaseFile, Passed(file.Pass()))); | 333 FROM_HERE, base::Bind(CloseBaseFile, Passed(file.Pass()))); |
| 292 return; | 334 return; |
| 293 } | 335 } |
| 294 if (!file.IsValid()) { | 336 if (!file.IsValid()) { |
| 295 // This translation will fail, but we need to retry any translation | 337 // This translation will fail, but we need to retry any translation |
| 296 // waiting for its result. | 338 // waiting for its result. |
| 297 LOG(ERROR) << "OnTempFileReturn: temp file creation failed"; | 339 LOG(ERROR) << "OnTempFileReturn: temp file creation failed"; |
| 298 std::string key(entry->second.cache_key); | 340 std::string key(entry->second.cache_key); |
| 299 entry->second.callback.Run(base::kInvalidPlatformFileValue, false); | 341 entry->second.callback.Run(base::File(), false); |
| 300 bool may_be_cached = TranslationMayBeCached(entry); | 342 bool may_be_cached = TranslationMayBeCached(entry); |
| 301 pending_translations_.erase(entry); | 343 pending_translations_.erase(entry); |
| 302 // No translations will be waiting for entries that will not be stored. | 344 // No translations will be waiting for entries that will not be stored. |
| 303 if (may_be_cached) | 345 if (may_be_cached) |
| 304 RequeryMatchingTranslations(key); | 346 RequeryMatchingTranslations(key); |
| 305 return; | 347 return; |
| 306 } | 348 } |
| 307 PendingTranslation* pt = &entry->second; | 349 PendingTranslation* pt = &entry->second; |
| 308 pt->got_nexe_fd = true; | 350 pt->got_nexe_fd = true; |
| 309 pt->nexe_fd = file.TakePlatformFile(); | 351 pt->nexe_fd = new base::File(file.Pass()); |
| 310 CheckCacheQueryReady(entry); | 352 CheckCacheQueryReady(entry); |
| 311 } | 353 } |
| 312 | 354 |
| 313 // Check whether both the cache query and the temp file have returned, and check | 355 // Check whether both the cache query and the temp file have returned, and check |
| 314 // whether we actually got a hit or not. | 356 // whether we actually got a hit or not. |
| 315 void PnaclHost::CheckCacheQueryReady( | 357 void PnaclHost::CheckCacheQueryReady( |
| 316 const PendingTranslationMap::iterator& entry) { | 358 const PendingTranslationMap::iterator& entry) { |
| 317 PendingTranslation* pt = &entry->second; | 359 PendingTranslation* pt = &entry->second; |
| 318 if (!(pt->got_cache_reply && pt->got_nexe_fd)) | 360 if (!(pt->got_cache_reply && pt->got_nexe_fd)) |
| 319 return; | 361 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 332 // and it's already gotten past this check and returned the miss. | 374 // and it's already gotten past this check and returned the miss. |
| 333 it->second.got_cache_reply && | 375 it->second.got_cache_reply && |
| 334 it->second.got_nexe_fd) { | 376 it->second.got_nexe_fd) { |
| 335 return; | 377 return; |
| 336 } | 378 } |
| 337 } | 379 } |
| 338 ReturnMiss(entry); | 380 ReturnMiss(entry); |
| 339 return; | 381 return; |
| 340 } | 382 } |
| 341 | 383 |
| 384 scoped_ptr<base::File> file(pt->nexe_fd); |
| 385 pt->nexe_fd = NULL; |
| 386 pt->got_nexe_fd = false; |
| 387 FileProxy* proxy(new FileProxy(file.Pass(), weak_factory_.GetWeakPtr())); |
| 388 |
| 342 if (!base::PostTaskAndReplyWithResult( | 389 if (!base::PostTaskAndReplyWithResult( |
| 343 BrowserThread::GetBlockingPool(), | 390 BrowserThread::GetBlockingPool(), |
| 344 FROM_HERE, | 391 FROM_HERE, |
| 345 base::Bind( | 392 base::Bind(&FileProxy::Write, base::Unretained(proxy), |
| 346 &PnaclHost::CopyBufferToFile, pt->nexe_fd, pt->nexe_read_buffer), | 393 pt->nexe_read_buffer), |
| 347 base::Bind(&PnaclHost::OnBufferCopiedToTempFile, | 394 base::Bind(&FileProxy::WriteDone, base::Owned(proxy), |
| 348 weak_factory_.GetWeakPtr(), | |
| 349 entry->first))) { | 395 entry->first))) { |
| 350 pt->callback.Run(base::kInvalidPlatformFileValue, false); | 396 pt->callback.Run(base::File(), false); |
| 351 } | 397 } |
| 352 } | 398 } |
| 353 | 399 |
| 354 //////////////////// GetNexeFd miss path | 400 //////////////////// GetNexeFd miss path |
| 355 // Return the temp fd to the renderer, reporting a miss. | 401 // Return the temp fd to the renderer, reporting a miss. |
| 356 void PnaclHost::ReturnMiss(const PendingTranslationMap::iterator& entry) { | 402 void PnaclHost::ReturnMiss(const PendingTranslationMap::iterator& entry) { |
| 357 // Return the fd | 403 // Return the fd |
| 358 PendingTranslation* pt = &entry->second; | 404 PendingTranslation* pt = &entry->second; |
| 359 NexeFdCallback cb(pt->callback); | 405 NexeFdCallback cb(pt->callback); |
| 360 if (pt->nexe_fd == base::kInvalidPlatformFileValue) { | 406 cb.Run(*pt->nexe_fd, false); |
| 361 // Bad FD is unrecoverable, so clear out the entry | 407 if (!pt->nexe_fd->IsValid()) { |
| 408 // Bad FD is unrecoverable, so clear out the entry. |
| 362 pending_translations_.erase(entry); | 409 pending_translations_.erase(entry); |
| 363 } | 410 } |
| 364 cb.Run(pt->nexe_fd, false); | |
| 365 } | 411 } |
| 366 | 412 |
| 367 // On error, just return a null refptr. | 413 // On error, just return a null refptr. |
| 368 // static | 414 // static |
| 369 scoped_refptr<net::DrainableIOBuffer> PnaclHost::CopyFileToBuffer( | 415 scoped_refptr<net::DrainableIOBuffer> PnaclHost::CopyFileToBuffer( |
| 370 base::PlatformFile fd) { | 416 scoped_ptr<base::File> file) { |
| 371 base::PlatformFileInfo info; | 417 base::File::Info info; |
| 372 scoped_refptr<net::DrainableIOBuffer> buffer; | 418 scoped_refptr<net::DrainableIOBuffer> buffer; |
| 373 bool error = false; | 419 bool error = false; |
| 374 if (!base::GetPlatformFileInfo(fd, &info) || | 420 if (!file->GetInfo(&info) || |
| 375 info.size >= std::numeric_limits<int>::max()) { | 421 info.size >= std::numeric_limits<int>::max()) { |
| 376 PLOG(ERROR) << "GetPlatformFileInfo failed"; | 422 PLOG(ERROR) << "File::GetInfo failed"; |
| 377 error = true; | 423 error = true; |
| 378 } else { | 424 } else { |
| 379 buffer = new net::DrainableIOBuffer( | 425 buffer = new net::DrainableIOBuffer( |
| 380 new net::IOBuffer(static_cast<int>(info.size)), info.size); | 426 new net::IOBuffer(static_cast<int>(info.size)), info.size); |
| 381 if (base::ReadPlatformFile(fd, 0, buffer->data(), buffer->size()) != | 427 if (file->Read(0, buffer->data(), buffer->size()) != info.size) { |
| 382 info.size) { | |
| 383 PLOG(ERROR) << "CopyFileToBuffer file read failed"; | 428 PLOG(ERROR) << "CopyFileToBuffer file read failed"; |
| 384 error = true; | 429 error = true; |
| 385 } | 430 } |
| 386 } | 431 } |
| 387 if (error) { | 432 if (error) { |
| 388 buffer = NULL; | 433 buffer = NULL; |
| 389 } | 434 } |
| 390 base::ClosePlatformFile(fd); | |
| 391 return buffer; | 435 return buffer; |
| 392 } | 436 } |
| 393 | 437 |
| 394 // Called by the renderer in the miss path to report a finished translation | 438 // Called by the renderer in the miss path to report a finished translation |
| 395 void PnaclHost::TranslationFinished(int render_process_id, | 439 void PnaclHost::TranslationFinished(int render_process_id, |
| 396 int pp_instance, | 440 int pp_instance, |
| 397 bool success) { | 441 bool success) { |
| 398 DCHECK(thread_checker_.CalledOnValidThread()); | 442 DCHECK(thread_checker_.CalledOnValidThread()); |
| 399 if (cache_state_ != CacheReady) | 443 if (cache_state_ != CacheReady) |
| 400 return; | 444 return; |
| 401 TranslationID id(render_process_id, pp_instance); | 445 TranslationID id(render_process_id, pp_instance); |
| 402 PendingTranslationMap::iterator entry(pending_translations_.find(id)); | 446 PendingTranslationMap::iterator entry(pending_translations_.find(id)); |
| 403 if (entry == pending_translations_.end()) { | 447 if (entry == pending_translations_.end()) { |
| 404 LOG(ERROR) << "TranslationFinished: TranslationID " << render_process_id | 448 LOG(ERROR) << "TranslationFinished: TranslationID " << render_process_id |
| 405 << "," << pp_instance << " not found."; | 449 << "," << pp_instance << " not found."; |
| 406 return; | 450 return; |
| 407 } | 451 } |
| 408 bool store_nexe = true; | 452 bool store_nexe = true; |
| 409 // If this is a premature response (i.e. we haven't returned a temp file | 453 // If this is a premature response (i.e. we haven't returned a temp file |
| 410 // yet) or if it's an unsuccessful translation, or if we are incognito, | 454 // yet) or if it's an unsuccessful translation, or if we are incognito, |
| 411 // don't store in the cache. | 455 // don't store in the cache. |
| 412 // TODO(dschuff): use a separate in-memory cache for incognito | 456 // TODO(dschuff): use a separate in-memory cache for incognito |
| 413 // translations. | 457 // translations. |
| 414 if (!entry->second.got_nexe_fd || !entry->second.got_cache_reply || | 458 if (!entry->second.got_nexe_fd || !entry->second.got_cache_reply || |
| 415 !success || !TranslationMayBeCached(entry)) { | 459 !success || !TranslationMayBeCached(entry)) { |
| 416 store_nexe = false; | 460 store_nexe = false; |
| 417 } else if (!base::PostTaskAndReplyWithResult( | 461 } else { |
| 418 BrowserThread::GetBlockingPool(), | 462 scoped_ptr<base::File> file(entry->second.nexe_fd); |
| 419 FROM_HERE, | 463 entry->second.nexe_fd = NULL; |
| 420 base::Bind(&PnaclHost::CopyFileToBuffer, | 464 entry->second.got_nexe_fd = false; |
| 421 entry->second.nexe_fd), | 465 |
| 422 base::Bind(&PnaclHost::StoreTranslatedNexe, | 466 if (!base::PostTaskAndReplyWithResult( |
| 423 weak_factory_.GetWeakPtr(), | 467 BrowserThread::GetBlockingPool(), |
| 424 id))) { | 468 FROM_HERE, |
| 425 store_nexe = false; | 469 base::Bind(&PnaclHost::CopyFileToBuffer, Passed(&file)), |
| 470 base::Bind(&PnaclHost::StoreTranslatedNexe, |
| 471 weak_factory_.GetWeakPtr(), |
| 472 id))) { |
| 473 store_nexe = false; |
| 474 } |
| 426 } | 475 } |
| 427 | 476 |
| 428 if (!store_nexe) { | 477 if (!store_nexe) { |
| 429 // If store_nexe is true, the fd will be closed by CopyFileToBuffer. | 478 // If store_nexe is true, the fd will be closed by CopyFileToBuffer. |
| 430 if (entry->second.got_nexe_fd) { | 479 if (entry->second.got_nexe_fd) { |
| 480 scoped_ptr<base::File> file(entry->second.nexe_fd); |
| 481 entry->second.nexe_fd = NULL; |
| 431 BrowserThread::PostBlockingPoolTask( | 482 BrowserThread::PostBlockingPoolTask( |
| 432 FROM_HERE, | 483 FROM_HERE, |
| 433 base::Bind(base::IgnoreResult(base::ClosePlatformFile), | 484 base::Bind(CloseScopedFile, Passed(&file))); |
| 434 entry->second.nexe_fd)); | |
| 435 } | 485 } |
| 436 pending_translations_.erase(entry); | 486 pending_translations_.erase(entry); |
| 437 } | 487 } |
| 438 } | 488 } |
| 439 | 489 |
| 440 // Store the translated nexe in the translation cache. Called back with the | 490 // Store the translated nexe in the translation cache. Called back with the |
| 441 // TranslationID from the host and the result of CopyFileToBuffer. | 491 // TranslationID from the host and the result of CopyFileToBuffer. |
| 442 // (Bound callbacks must re-lookup the TranslationID because the translation | 492 // (Bound callbacks must re-lookup the TranslationID because the translation |
| 443 // could be cancelled before they get called). | 493 // could be cancelled before they get called). |
| 444 void PnaclHost::StoreTranslatedNexe( | 494 void PnaclHost::StoreTranslatedNexe( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 disk_cache_->GetNexe(key, | 550 disk_cache_->GetNexe(key, |
| 501 base::Bind(&PnaclHost::OnCacheQueryReturn, | 551 base::Bind(&PnaclHost::OnCacheQueryReturn, |
| 502 weak_factory_.GetWeakPtr(), | 552 weak_factory_.GetWeakPtr(), |
| 503 it->first)); | 553 it->first)); |
| 504 } | 554 } |
| 505 } | 555 } |
| 506 } | 556 } |
| 507 | 557 |
| 508 //////////////////// GetNexeFd hit path | 558 //////////////////// GetNexeFd hit path |
| 509 | 559 |
| 510 // static | |
| 511 int PnaclHost::CopyBufferToFile(base::PlatformFile fd, | |
| 512 scoped_refptr<net::DrainableIOBuffer> buffer) { | |
| 513 int rv = base::WritePlatformFile(fd, 0, buffer->data(), buffer->size()); | |
| 514 if (rv == -1) | |
| 515 PLOG(ERROR) << "CopyBufferToFile write error"; | |
| 516 return rv; | |
| 517 } | |
| 518 | |
| 519 void PnaclHost::OnBufferCopiedToTempFile(const TranslationID& id, | 560 void PnaclHost::OnBufferCopiedToTempFile(const TranslationID& id, |
| 561 scoped_ptr<base::File> file, |
| 520 int file_error) { | 562 int file_error) { |
| 521 DCHECK(thread_checker_.CalledOnValidThread()); | 563 DCHECK(thread_checker_.CalledOnValidThread()); |
| 522 PendingTranslationMap::iterator entry(pending_translations_.find(id)); | 564 PendingTranslationMap::iterator entry(pending_translations_.find(id)); |
| 523 if (entry == pending_translations_.end()) { | 565 if (entry == pending_translations_.end()) { |
| 566 BrowserThread::PostBlockingPoolTask( |
| 567 FROM_HERE, |
| 568 base::Bind(CloseScopedFile, Passed(&file))); |
| 524 return; | 569 return; |
| 525 } | 570 } |
| 526 if (file_error == -1) { | 571 if (file_error == -1) { |
| 527 // Write error on the temp file. Request a new file and start over. | 572 // Write error on the temp file. Request a new file and start over. |
| 528 BrowserThread::PostBlockingPoolTask( | 573 BrowserThread::PostBlockingPoolTask( |
| 529 FROM_HERE, | 574 FROM_HERE, |
| 530 base::Bind(base::IgnoreResult(base::ClosePlatformFile), | 575 base::Bind(CloseScopedFile, Passed(&file))); |
| 531 entry->second.nexe_fd)); | |
| 532 entry->second.got_nexe_fd = false; | |
| 533 CreateTemporaryFile(base::Bind(&PnaclHost::OnTempFileReturn, | 576 CreateTemporaryFile(base::Bind(&PnaclHost::OnTempFileReturn, |
| 534 weak_factory_.GetWeakPtr(), | 577 weak_factory_.GetWeakPtr(), |
| 535 entry->first)); | 578 entry->first)); |
| 536 return; | 579 return; |
| 537 } | 580 } |
| 538 base::PlatformFile fd = entry->second.nexe_fd; | 581 entry->second.callback.Run(*file.get(), true); |
| 539 entry->second.callback.Run(fd, true); | |
| 540 BrowserThread::PostBlockingPoolTask( | 582 BrowserThread::PostBlockingPoolTask( |
| 541 FROM_HERE, base::Bind(base::IgnoreResult(base::ClosePlatformFile), fd)); | 583 FROM_HERE, |
| 584 base::Bind(CloseScopedFile, Passed(&file))); |
| 542 pending_translations_.erase(entry); | 585 pending_translations_.erase(entry); |
| 543 } | 586 } |
| 544 | 587 |
| 545 /////////////////// | 588 /////////////////// |
| 546 | 589 |
| 547 void PnaclHost::RendererClosing(int render_process_id) { | 590 void PnaclHost::RendererClosing(int render_process_id) { |
| 548 DCHECK(thread_checker_.CalledOnValidThread()); | 591 DCHECK(thread_checker_.CalledOnValidThread()); |
| 549 if (cache_state_ != CacheReady) | 592 if (cache_state_ != CacheReady) |
| 550 return; | 593 return; |
| 551 for (PendingTranslationMap::iterator it = pending_translations_.begin(); | 594 for (PendingTranslationMap::iterator it = pending_translations_.begin(); |
| 552 it != pending_translations_.end();) { | 595 it != pending_translations_.end();) { |
| 553 PendingTranslationMap::iterator to_erase(it++); | 596 PendingTranslationMap::iterator to_erase(it++); |
| 554 if (to_erase->first.first == render_process_id) { | 597 if (to_erase->first.first == render_process_id) { |
| 555 // Clean up the open files. | 598 // Clean up the open files. |
| 599 scoped_ptr<base::File> file(to_erase->second.nexe_fd); |
| 600 to_erase->second.nexe_fd = NULL; |
| 556 BrowserThread::PostBlockingPoolTask( | 601 BrowserThread::PostBlockingPoolTask( |
| 557 FROM_HERE, | 602 FROM_HERE, |
| 558 base::Bind(base::IgnoreResult(base::ClosePlatformFile), | 603 base::Bind(CloseScopedFile, Passed(&file))); |
| 559 to_erase->second.nexe_fd)); | |
| 560 std::string key(to_erase->second.cache_key); | 604 std::string key(to_erase->second.cache_key); |
| 561 bool may_be_cached = TranslationMayBeCached(to_erase); | 605 bool may_be_cached = TranslationMayBeCached(to_erase); |
| 562 pending_translations_.erase(to_erase); | 606 pending_translations_.erase(to_erase); |
| 563 // No translations will be waiting for entries that will not be stored. | 607 // No translations will be waiting for entries that will not be stored. |
| 564 if (may_be_cached) | 608 if (may_be_cached) |
| 565 RequeryMatchingTranslations(key); | 609 RequeryMatchingTranslations(key); |
| 566 } | 610 } |
| 567 } | 611 } |
| 568 BrowserThread::PostTask( | 612 BrowserThread::PostTask( |
| 569 BrowserThread::IO, | 613 BrowserThread::IO, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 DCHECK(pending_backend_operations_ >= 0); | 680 DCHECK(pending_backend_operations_ >= 0); |
| 637 if (pending_translations_.empty() && | 681 if (pending_translations_.empty() && |
| 638 pending_backend_operations_ <= 0 && | 682 pending_backend_operations_ <= 0 && |
| 639 cache_state_ == CacheReady) { | 683 cache_state_ == CacheReady) { |
| 640 cache_state_ = CacheUninitialized; | 684 cache_state_ = CacheUninitialized; |
| 641 disk_cache_.reset(); | 685 disk_cache_.reset(); |
| 642 } | 686 } |
| 643 } | 687 } |
| 644 | 688 |
| 645 } // namespace pnacl | 689 } // namespace pnacl |
| OLD | NEW |