| 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 "chrome/browser/nacl_host/pnacl_host.h" | 5 #include "chrome/browser/nacl_host/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" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 render_view_id(0), | 38 render_view_id(0), |
| 39 nexe_fd(base::kInvalidPlatformFileValue), | 39 nexe_fd(base::kInvalidPlatformFileValue), |
| 40 got_nexe_fd(false), | 40 got_nexe_fd(false), |
| 41 got_cache_reply(false), | 41 got_cache_reply(false), |
| 42 got_cache_hit(false), | 42 got_cache_hit(false), |
| 43 is_incognito(false), | 43 is_incognito(false), |
| 44 callback(NexeFdCallback()), | 44 callback(NexeFdCallback()), |
| 45 cache_info(nacl::PnaclCacheInfo()) {} | 45 cache_info(nacl::PnaclCacheInfo()) {} |
| 46 PnaclHost::PendingTranslation::~PendingTranslation() {} | 46 PnaclHost::PendingTranslation::~PendingTranslation() {} |
| 47 | 47 |
| 48 bool PnaclHost::TranslationMayBeCached( | |
| 49 const PendingTranslationMap::iterator& entry) { | |
| 50 return !entry->second.is_incognito && | |
| 51 !entry->second.cache_info.has_no_store_header; | |
| 52 } | |
| 53 | |
| 54 /////////////////////////////////////// Initialization | 48 /////////////////////////////////////// Initialization |
| 55 | 49 |
| 56 static base::FilePath GetCachePath() { | 50 static base::FilePath GetCachePath() { |
| 57 NaClBrowserDelegate* browser_delegate = NaClBrowser::GetDelegate(); | 51 NaClBrowserDelegate* browser_delegate = NaClBrowser::GetDelegate(); |
| 58 // Determine where the translation cache resides in the file system. It | 52 // Determine where the translation cache resides in the file system. It |
| 59 // exists in Chrome's cache directory and is not tied to any specific | 53 // exists in Chrome's cache directory and is not tied to any specific |
| 60 // profile. If we fail, return an empty path. | 54 // profile. If we fail, return an empty path. |
| 61 // Start by finding the user data directory. | 55 // Start by finding the user data directory. |
| 62 base::FilePath user_data_dir; | 56 base::FilePath user_data_dir; |
| 63 if (!browser_delegate || | 57 if (!browser_delegate || |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 LOG(ERROR) << "OnTempFileReturn: id not found"; | 261 LOG(ERROR) << "OnTempFileReturn: id not found"; |
| 268 BrowserThread::PostBlockingPoolTask( | 262 BrowserThread::PostBlockingPoolTask( |
| 269 FROM_HERE, base::Bind(base::IgnoreResult(base::ClosePlatformFile), fd)); | 263 FROM_HERE, base::Bind(base::IgnoreResult(base::ClosePlatformFile), fd)); |
| 270 return; | 264 return; |
| 271 } | 265 } |
| 272 if (fd == base::kInvalidPlatformFileValue) { | 266 if (fd == base::kInvalidPlatformFileValue) { |
| 273 // This translation will fail, but we need to retry any translation | 267 // This translation will fail, but we need to retry any translation |
| 274 // waiting for its result. | 268 // waiting for its result. |
| 275 LOG(ERROR) << "OnTempFileReturn: temp file creation failed"; | 269 LOG(ERROR) << "OnTempFileReturn: temp file creation failed"; |
| 276 std::string key(entry->second.cache_key); | 270 std::string key(entry->second.cache_key); |
| 271 bool is_incognito = entry->second.is_incognito; |
| 277 entry->second.callback.Run(fd, false); | 272 entry->second.callback.Run(fd, false); |
| 278 pending_translations_.erase(entry); | 273 pending_translations_.erase(entry); |
| 279 // No translations will be waiting for entries that will not be stored. | 274 // No translations will be waiting for an incongnito translation |
| 280 if (TranslationMayBeCached(entry)) | 275 if (!is_incognito) |
| 281 RequeryMatchingTranslations(key); | 276 RequeryMatchingTranslations(key); |
| 282 return; | 277 return; |
| 283 } | 278 } |
| 284 PendingTranslation* pt = &entry->second; | 279 PendingTranslation* pt = &entry->second; |
| 285 pt->got_nexe_fd = true; | 280 pt->got_nexe_fd = true; |
| 286 pt->nexe_fd = fd; | 281 pt->nexe_fd = fd; |
| 287 CheckCacheQueryReady(entry); | 282 CheckCacheQueryReady(entry); |
| 288 } | 283 } |
| 289 | 284 |
| 290 // Check whether both the cache query and the temp file have returned, and check | 285 // Check whether both the cache query and the temp file have returned, and check |
| 291 // whether we actually got a hit or not. | 286 // whether we actually got a hit or not. |
| 292 void PnaclHost::CheckCacheQueryReady( | 287 void PnaclHost::CheckCacheQueryReady( |
| 293 const PendingTranslationMap::iterator& entry) { | 288 const PendingTranslationMap::iterator& entry) { |
| 294 PendingTranslation* pt = &entry->second; | 289 PendingTranslation* pt = &entry->second; |
| 295 if (!(pt->got_cache_reply && pt->got_nexe_fd)) | 290 if (!(pt->got_cache_reply && pt->got_nexe_fd)) |
| 296 return; | 291 return; |
| 297 if (!pt->got_cache_hit) { | 292 if (!pt->got_cache_hit) { |
| 298 // Check if there is already a pending translation for this file. If there | 293 // Check if there is already a pending translation for this file. If there |
| 299 // is, we will wait for it to come back, to avoid redundant translations. | 294 // is, we will wait for it to come back, to avoid redundant translations. |
| 300 for (PendingTranslationMap::iterator it = pending_translations_.begin(); | 295 for (PendingTranslationMap::iterator it = pending_translations_.begin(); |
| 301 it != pending_translations_.end(); | 296 it != pending_translations_.end(); |
| 302 ++it) { | 297 ++it) { |
| 303 // Another translation matches if it's a request for the same file, | 298 // Another translation matches if it's a request for the same file, |
| 304 if (it->second.cache_key == entry->second.cache_key && | 299 if (it->second.cache_key == entry->second.cache_key && |
| 305 // and it's not this translation, | 300 // and it's not this translation, |
| 306 it->first != entry->first && | 301 it->first != entry->first && |
| 307 // and it can be stored in the cache, | 302 // and it's not incognito, |
| 308 TranslationMayBeCached(it) && | 303 !it->second.is_incognito && |
| 309 // and it's already gotten past this check and returned the miss. | 304 // and if it's already gotten past this check and returned the miss. |
| 310 it->second.got_cache_reply && | 305 it->second.got_cache_reply && |
| 311 it->second.got_nexe_fd) { | 306 it->second.got_nexe_fd) { |
| 312 return; | 307 return; |
| 313 } | 308 } |
| 314 } | 309 } |
| 315 ReturnMiss(entry); | 310 ReturnMiss(entry); |
| 316 return; | 311 return; |
| 317 } | 312 } |
| 318 | 313 |
| 319 if (!base::PostTaskAndReplyWithResult( | 314 if (!base::PostTaskAndReplyWithResult( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 << "," << pp_instance << " not found."; | 377 << "," << pp_instance << " not found."; |
| 383 return; | 378 return; |
| 384 } | 379 } |
| 385 bool store_nexe = true; | 380 bool store_nexe = true; |
| 386 // If this is a premature response (i.e. we haven't returned a temp file | 381 // If this is a premature response (i.e. we haven't returned a temp file |
| 387 // yet) or if it's an unsuccessful translation, or if we are incognito, | 382 // yet) or if it's an unsuccessful translation, or if we are incognito, |
| 388 // don't store in the cache. | 383 // don't store in the cache. |
| 389 // TODO(dschuff): use a separate in-memory cache for incognito | 384 // TODO(dschuff): use a separate in-memory cache for incognito |
| 390 // translations. | 385 // translations. |
| 391 if (!entry->second.got_nexe_fd || !entry->second.got_cache_reply || | 386 if (!entry->second.got_nexe_fd || !entry->second.got_cache_reply || |
| 392 !success || !TranslationMayBeCached(entry)) { | 387 !success || entry->second.is_incognito) { |
| 393 store_nexe = false; | 388 store_nexe = false; |
| 394 } else if (!base::PostTaskAndReplyWithResult( | 389 } else if (!base::PostTaskAndReplyWithResult( |
| 395 BrowserThread::GetBlockingPool(), | 390 BrowserThread::GetBlockingPool(), |
| 396 FROM_HERE, | 391 FROM_HERE, |
| 397 base::Bind(&PnaclHost::CopyFileToBuffer, | 392 base::Bind(&PnaclHost::CopyFileToBuffer, |
| 398 entry->second.nexe_fd), | 393 entry->second.nexe_fd), |
| 399 base::Bind(&PnaclHost::StoreTranslatedNexe, | 394 base::Bind(&PnaclHost::StoreTranslatedNexe, |
| 400 weak_factory_.GetWeakPtr(), | 395 weak_factory_.GetWeakPtr(), |
| 401 id))) { | 396 id))) { |
| 402 store_nexe = false; | 397 store_nexe = false; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 for (PendingTranslationMap::iterator it = pending_translations_.begin(); | 518 for (PendingTranslationMap::iterator it = pending_translations_.begin(); |
| 524 it != pending_translations_.end();) { | 519 it != pending_translations_.end();) { |
| 525 PendingTranslationMap::iterator to_erase(it++); | 520 PendingTranslationMap::iterator to_erase(it++); |
| 526 if (to_erase->first.first == render_process_id) { | 521 if (to_erase->first.first == render_process_id) { |
| 527 // Clean up the open files. | 522 // Clean up the open files. |
| 528 BrowserThread::PostBlockingPoolTask( | 523 BrowserThread::PostBlockingPoolTask( |
| 529 FROM_HERE, | 524 FROM_HERE, |
| 530 base::Bind(base::IgnoreResult(base::ClosePlatformFile), | 525 base::Bind(base::IgnoreResult(base::ClosePlatformFile), |
| 531 to_erase->second.nexe_fd)); | 526 to_erase->second.nexe_fd)); |
| 532 std::string key(to_erase->second.cache_key); | 527 std::string key(to_erase->second.cache_key); |
| 528 bool is_incognito = to_erase->second.is_incognito; |
| 533 pending_translations_.erase(to_erase); | 529 pending_translations_.erase(to_erase); |
| 534 // No translations will be waiting for entries that will not be stored. | 530 // No translations will be blocked waiting for an incongnito translation |
| 535 if (TranslationMayBeCached(to_erase)) | 531 if (!is_incognito) |
| 536 RequeryMatchingTranslations(key); | 532 RequeryMatchingTranslations(key); |
| 537 } | 533 } |
| 538 } | 534 } |
| 539 if (pending_translations_.empty()) { | 535 if (pending_translations_.empty()) { |
| 540 cache_state_ = CacheUninitialized; | 536 cache_state_ = CacheUninitialized; |
| 541 // Freeing the backend causes it to flush to disk, so do it when the | 537 // Freeing the backend causes it to flush to disk, so do it when the |
| 542 // last renderer closes rather than on destruction. | 538 // last renderer closes rather than on destruction. |
| 543 disk_cache_.reset(); | 539 disk_cache_.reset(); |
| 544 } | 540 } |
| 545 } | 541 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 572 end_time, | 568 end_time, |
| 573 base::Bind(&PnaclHost::OnEntriesDoomed, callback)); | 569 base::Bind(&PnaclHost::OnEntriesDoomed, callback)); |
| 574 if (rv != net::ERR_IO_PENDING) | 570 if (rv != net::ERR_IO_PENDING) |
| 575 OnEntriesDoomed(callback, rv); | 571 OnEntriesDoomed(callback, rv); |
| 576 } | 572 } |
| 577 | 573 |
| 578 // static | 574 // static |
| 579 void PnaclHost::OnEntriesDoomed(const base::Closure& callback, int net_error) { | 575 void PnaclHost::OnEntriesDoomed(const base::Closure& callback, int net_error) { |
| 580 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback); | 576 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback); |
| 581 } | 577 } |
| OLD | NEW |