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 |