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 |