| 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 static const base::FilePath::CharType kTranslationCacheDirectoryName[] = | 24 static const base::FilePath::CharType kTranslationCacheDirectoryName[] = |
| 24 FILE_PATH_LITERAL("PnaclTranslationCache"); | 25 FILE_PATH_LITERAL("PnaclTranslationCache"); |
| 25 // Delay to wait for initialization of the cache backend | 26 // Delay to wait for initialization of the cache backend |
| 26 static const int kTranslationCacheInitializationDelayMs = 20; | 27 static const int kTranslationCacheInitializationDelayMs = 20; |
| 28 |
| 29 void CloseBaseFile(base::File file) { |
| 30 // Not really needed because the file will go out of scope here. |
| 31 file.Close(); |
| 32 } |
| 33 |
| 27 } | 34 } |
| 28 | 35 |
| 29 namespace pnacl { | 36 namespace pnacl { |
| 30 | 37 |
| 31 PnaclHost::PnaclHost() | 38 PnaclHost::PnaclHost() |
| 32 : pending_backend_operations_(0), | 39 : pending_backend_operations_(0), |
| 33 cache_state_(CacheUninitialized), | 40 cache_state_(CacheUninitialized), |
| 34 weak_factory_(this) {} | 41 weak_factory_(this) {} |
| 35 | 42 |
| 36 PnaclHost::~PnaclHost() { | 43 PnaclHost::~PnaclHost() { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 | 141 |
| 135 ///////////////////////////////////////// Temp files | 142 ///////////////////////////////////////// Temp files |
| 136 | 143 |
| 137 // Create a temporary file on the blocking pool | 144 // Create a temporary file on the blocking pool |
| 138 // static | 145 // static |
| 139 void PnaclHost::DoCreateTemporaryFile(base::FilePath temp_dir, | 146 void PnaclHost::DoCreateTemporaryFile(base::FilePath temp_dir, |
| 140 TempFileCallback cb) { | 147 TempFileCallback cb) { |
| 141 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 148 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 142 | 149 |
| 143 base::FilePath file_path; | 150 base::FilePath file_path; |
| 144 base::PlatformFile file_handle(base::kInvalidPlatformFileValue); | 151 base::File file; |
| 145 bool rv = temp_dir.empty() | 152 bool rv = temp_dir.empty() |
| 146 ? base::CreateTemporaryFile(&file_path) | 153 ? base::CreateTemporaryFile(&file_path) |
| 147 : base::CreateTemporaryFileInDir(temp_dir, &file_path); | 154 : base::CreateTemporaryFileInDir(temp_dir, &file_path); |
| 148 if (!rv) { | 155 if (!rv) { |
| 149 PLOG(ERROR) << "Temp file creation failed."; | 156 PLOG(ERROR) << "Temp file creation failed."; |
| 150 } else { | 157 } else { |
| 151 base::PlatformFileError error; | 158 file.Initialize( |
| 152 file_handle = base::CreatePlatformFile( | |
| 153 file_path, | 159 file_path, |
| 154 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_READ | | 160 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ | |
| 155 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_TEMPORARY | | 161 base::File::FLAG_WRITE | base::File::FLAG_TEMPORARY | |
| 156 base::PLATFORM_FILE_DELETE_ON_CLOSE, | 162 base::File::FLAG_DELETE_ON_CLOSE); |
| 157 NULL, | |
| 158 &error); | |
| 159 | 163 |
| 160 if (error != base::PLATFORM_FILE_OK) { | 164 if (!file.IsValid()) |
| 161 PLOG(ERROR) << "Temp file open failed: " << error; | 165 PLOG(ERROR) << "Temp file open failed: " << file.error_details(); |
| 162 file_handle = base::kInvalidPlatformFileValue; | |
| 163 } | |
| 164 } | 166 } |
| 165 BrowserThread::PostTask( | 167 BrowserThread::PostTask( |
| 166 BrowserThread::IO, FROM_HERE, base::Bind(cb, file_handle)); | 168 BrowserThread::IO, FROM_HERE, base::Bind(cb, Passed(file.Pass()))); |
| 167 } | 169 } |
| 168 | 170 |
| 169 void PnaclHost::CreateTemporaryFile(TempFileCallback cb) { | 171 void PnaclHost::CreateTemporaryFile(TempFileCallback cb) { |
| 170 if (!BrowserThread::PostBlockingPoolSequencedTask( | 172 if (!BrowserThread::PostBlockingPoolSequencedTask( |
| 171 "PnaclHostCreateTempFile", | 173 "PnaclHostCreateTempFile", |
| 172 FROM_HERE, | 174 FROM_HERE, |
| 173 base::Bind(&PnaclHost::DoCreateTemporaryFile, temp_dir_, cb))) { | 175 base::Bind(&PnaclHost::DoCreateTemporaryFile, temp_dir_, cb))) { |
| 174 DCHECK(thread_checker_.CalledOnValidThread()); | 176 DCHECK(thread_checker_.CalledOnValidThread()); |
| 175 cb.Run(base::kInvalidPlatformFileValue); | 177 cb.Run(base::File()); |
| 176 } | 178 } |
| 177 } | 179 } |
| 178 | 180 |
| 179 ///////////////////////////////////////// GetNexeFd implementation | 181 ///////////////////////////////////////// GetNexeFd implementation |
| 180 ////////////////////// Common steps | 182 ////////////////////// Common steps |
| 181 | 183 |
| 182 void PnaclHost::GetNexeFd(int render_process_id, | 184 void PnaclHost::GetNexeFd(int render_process_id, |
| 183 int render_view_id, | 185 int render_view_id, |
| 184 int pp_instance, | 186 int pp_instance, |
| 185 bool is_incognito, | 187 bool is_incognito, |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 } | 268 } |
| 267 PendingTranslation* pt = &entry->second; | 269 PendingTranslation* pt = &entry->second; |
| 268 pt->got_cache_reply = true; | 270 pt->got_cache_reply = true; |
| 269 pt->got_cache_hit = (net_error == net::OK); | 271 pt->got_cache_hit = (net_error == net::OK); |
| 270 if (pt->got_cache_hit) | 272 if (pt->got_cache_hit) |
| 271 pt->nexe_read_buffer = buffer; | 273 pt->nexe_read_buffer = buffer; |
| 272 CheckCacheQueryReady(entry); | 274 CheckCacheQueryReady(entry); |
| 273 } | 275 } |
| 274 | 276 |
| 275 // Callback from temp file creation. |id| is bound from | 277 // Callback from temp file creation. |id| is bound from |
| 276 // SendCacheQueryAndTempFileRequest, and fd is the created file descriptor. | 278 // SendCacheQueryAndTempFileRequest, and |file| is the created file. |
| 277 // If there was an error, fd is kInvalidPlatformFileValue. | 279 // If there was an error, fd is kInvalidPlatformFileValue. |
| 278 // (Bound callbacks must re-lookup the TranslationID because the translation | 280 // (Bound callbacks must re-lookup the TranslationID because the translation |
| 279 // could be cancelled before they get called). | 281 // could be cancelled before they get called). |
| 280 void PnaclHost::OnTempFileReturn(const TranslationID& id, | 282 void PnaclHost::OnTempFileReturn(const TranslationID& id, |
| 281 base::PlatformFile fd) { | 283 base::File file) { |
| 282 DCHECK(thread_checker_.CalledOnValidThread()); | 284 DCHECK(thread_checker_.CalledOnValidThread()); |
| 283 PendingTranslationMap::iterator entry(pending_translations_.find(id)); | 285 PendingTranslationMap::iterator entry(pending_translations_.find(id)); |
| 284 if (entry == pending_translations_.end()) { | 286 if (entry == pending_translations_.end()) { |
| 285 // The renderer may have signaled an error or closed while the temp | 287 // The renderer may have signaled an error or closed while the temp |
| 286 // file was being created. | 288 // file was being created. |
| 287 LOG(ERROR) << "OnTempFileReturn: id not found"; | 289 LOG(ERROR) << "OnTempFileReturn: id not found"; |
| 288 BrowserThread::PostBlockingPoolTask( | 290 BrowserThread::PostBlockingPoolTask( |
| 289 FROM_HERE, base::Bind(base::IgnoreResult(base::ClosePlatformFile), fd)); | 291 FROM_HERE, base::Bind(CloseBaseFile, Passed(file.Pass()))); |
| 290 return; | 292 return; |
| 291 } | 293 } |
| 292 if (fd == base::kInvalidPlatformFileValue) { | 294 if (!file.IsValid()) { |
| 293 // This translation will fail, but we need to retry any translation | 295 // This translation will fail, but we need to retry any translation |
| 294 // waiting for its result. | 296 // waiting for its result. |
| 295 LOG(ERROR) << "OnTempFileReturn: temp file creation failed"; | 297 LOG(ERROR) << "OnTempFileReturn: temp file creation failed"; |
| 296 std::string key(entry->second.cache_key); | 298 std::string key(entry->second.cache_key); |
| 297 entry->second.callback.Run(fd, false); | 299 entry->second.callback.Run(base::kInvalidPlatformFileValue, false); |
| 298 bool may_be_cached = TranslationMayBeCached(entry); | 300 bool may_be_cached = TranslationMayBeCached(entry); |
| 299 pending_translations_.erase(entry); | 301 pending_translations_.erase(entry); |
| 300 // No translations will be waiting for entries that will not be stored. | 302 // No translations will be waiting for entries that will not be stored. |
| 301 if (may_be_cached) | 303 if (may_be_cached) |
| 302 RequeryMatchingTranslations(key); | 304 RequeryMatchingTranslations(key); |
| 303 return; | 305 return; |
| 304 } | 306 } |
| 305 PendingTranslation* pt = &entry->second; | 307 PendingTranslation* pt = &entry->second; |
| 306 pt->got_nexe_fd = true; | 308 pt->got_nexe_fd = true; |
| 307 pt->nexe_fd = fd; | 309 pt->nexe_fd = file.TakePlatformFile(); |
| 308 CheckCacheQueryReady(entry); | 310 CheckCacheQueryReady(entry); |
| 309 } | 311 } |
| 310 | 312 |
| 311 // Check whether both the cache query and the temp file have returned, and check | 313 // Check whether both the cache query and the temp file have returned, and check |
| 312 // whether we actually got a hit or not. | 314 // whether we actually got a hit or not. |
| 313 void PnaclHost::CheckCacheQueryReady( | 315 void PnaclHost::CheckCacheQueryReady( |
| 314 const PendingTranslationMap::iterator& entry) { | 316 const PendingTranslationMap::iterator& entry) { |
| 315 PendingTranslation* pt = &entry->second; | 317 PendingTranslation* pt = &entry->second; |
| 316 if (!(pt->got_cache_reply && pt->got_nexe_fd)) | 318 if (!(pt->got_cache_reply && pt->got_nexe_fd)) |
| 317 return; | 319 return; |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 DCHECK(pending_backend_operations_ >= 0); | 636 DCHECK(pending_backend_operations_ >= 0); |
| 635 if (pending_translations_.empty() && | 637 if (pending_translations_.empty() && |
| 636 pending_backend_operations_ <= 0 && | 638 pending_backend_operations_ <= 0 && |
| 637 cache_state_ == CacheReady) { | 639 cache_state_ == CacheReady) { |
| 638 cache_state_ = CacheUninitialized; | 640 cache_state_ = CacheUninitialized; |
| 639 disk_cache_.reset(); | 641 disk_cache_.reset(); |
| 640 } | 642 } |
| 641 } | 643 } |
| 642 | 644 |
| 643 } // namespace pnacl | 645 } // namespace pnacl |
| OLD | NEW |