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