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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 // Append the base file name to the cache directory. | 65 // Append the base file name to the cache directory. |
66 return cache_file_path.Append(kTranslationCacheDirectoryName); | 66 return cache_file_path.Append(kTranslationCacheDirectoryName); |
67 } | 67 } |
68 | 68 |
69 void PnaclHost::OnCacheInitialized(int net_error) { | 69 void PnaclHost::OnCacheInitialized(int net_error) { |
70 DCHECK(thread_checker_.CalledOnValidThread()); | 70 DCHECK(thread_checker_.CalledOnValidThread()); |
71 // If the cache was cleared before the load completed, ignore. | 71 // If the cache was cleared before the load completed, ignore. |
72 if (cache_state_ == CacheReady) | 72 if (cache_state_ == CacheReady) |
73 return; | 73 return; |
74 if (net_error != net::OK) { | 74 if (net_error != net::OK) { |
75 LOG(ERROR) << "PNaCl translation cache initalization failure: " << net_error | 75 // This will cause the cache to attempt to re-init on the next call to |
76 << "\n"; | 76 // GetNexeFd. |
| 77 cache_state_ = CacheUninitialized; |
77 } else { | 78 } else { |
78 cache_state_ = CacheReady; | 79 cache_state_ = CacheReady; |
79 } | 80 } |
80 } | 81 } |
81 | 82 |
82 void PnaclHost::Init() { | 83 void PnaclHost::Init() { |
83 // Extra check that we're on the real IO thread since this version of | 84 // Extra check that we're on the real IO thread since this version of |
84 // Init isn't used in unit tests. | 85 // Init isn't used in unit tests. |
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
86 DCHECK(thread_checker_.CalledOnValidThread()); | 87 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 26 matching lines...) Expand all Loading... |
113 // Create a temporary file on the blocking pool | 114 // Create a temporary file on the blocking pool |
114 // static | 115 // static |
115 base::PlatformFile PnaclHost::DoCreateTemporaryFile(base::FilePath temp_dir) { | 116 base::PlatformFile PnaclHost::DoCreateTemporaryFile(base::FilePath temp_dir) { |
116 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 117 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
117 | 118 |
118 base::FilePath file_path; | 119 base::FilePath file_path; |
119 bool rv = temp_dir.empty() | 120 bool rv = temp_dir.empty() |
120 ? file_util::CreateTemporaryFile(&file_path) | 121 ? file_util::CreateTemporaryFile(&file_path) |
121 : file_util::CreateTemporaryFileInDir(temp_dir, &file_path); | 122 : file_util::CreateTemporaryFileInDir(temp_dir, &file_path); |
122 | 123 |
123 if (!rv) | 124 if (!rv) { |
| 125 LOG(ERROR) << "PnaclHost:: Temp file creation failed."; |
124 return base::kInvalidPlatformFileValue; | 126 return base::kInvalidPlatformFileValue; |
| 127 } |
125 base::PlatformFileError error; | 128 base::PlatformFileError error; |
126 base::PlatformFile file_handle(base::CreatePlatformFile( | 129 base::PlatformFile file_handle(base::CreatePlatformFile( |
127 file_path, | 130 file_path, |
128 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_READ | | 131 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_READ | |
129 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_TEMPORARY | | 132 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_TEMPORARY | |
130 base::PLATFORM_FILE_DELETE_ON_CLOSE, | 133 base::PLATFORM_FILE_DELETE_ON_CLOSE, |
131 NULL, | 134 NULL, |
132 &error)); | 135 &error)); |
133 | 136 |
134 if (error != base::PLATFORM_FILE_OK) | 137 if (error != base::PLATFORM_FILE_OK) { |
| 138 LOG(ERROR) << "PnaclHost: Temp file open failed: " << error; |
135 return base::kInvalidPlatformFileValue; | 139 return base::kInvalidPlatformFileValue; |
| 140 } |
136 | 141 |
137 return file_handle; | 142 return file_handle; |
138 } | 143 } |
139 | 144 |
140 void PnaclHost::CreateTemporaryFile(TempFileCallback cb) { | 145 void PnaclHost::CreateTemporaryFile(TempFileCallback cb) { |
141 if (!base::PostTaskAndReplyWithResult( | 146 if (!base::PostTaskAndReplyWithResult( |
142 BrowserThread::GetBlockingPool(), | 147 BrowserThread::GetBlockingPool(), |
143 FROM_HERE, | 148 FROM_HERE, |
144 base::Bind(&PnaclHost::DoCreateTemporaryFile, temp_dir_), | 149 base::Bind(&PnaclHost::DoCreateTemporaryFile, temp_dir_), |
145 cb)) { | 150 cb)) { |
146 DCHECK(thread_checker_.CalledOnValidThread()); | 151 DCHECK(thread_checker_.CalledOnValidThread()); |
147 cb.Run(base::kInvalidPlatformFileValue); | 152 cb.Run(base::kInvalidPlatformFileValue); |
148 } | 153 } |
149 } | 154 } |
150 | 155 |
151 ///////////////////////////////////////// GetNexeFd implementation | 156 ///////////////////////////////////////// GetNexeFd implementation |
152 ////////////////////// Common steps | 157 ////////////////////// Common steps |
153 | 158 |
154 void PnaclHost::GetNexeFd(int render_process_id, | 159 void PnaclHost::GetNexeFd(int render_process_id, |
155 int render_view_id, | 160 int render_view_id, |
156 int pp_instance, | 161 int pp_instance, |
157 bool is_incognito, | 162 bool is_incognito, |
158 const nacl::PnaclCacheInfo& cache_info, | 163 const nacl::PnaclCacheInfo& cache_info, |
159 const NexeFdCallback& cb) { | 164 const NexeFdCallback& cb) { |
160 DCHECK(thread_checker_.CalledOnValidThread()); | 165 DCHECK(thread_checker_.CalledOnValidThread()); |
161 if (cache_state_ == CacheUninitialized) { | 166 if (cache_state_ == CacheUninitialized) { |
162 Init(); | 167 Init(); |
163 } | 168 } |
164 if (cache_state_ == CacheInitializing) { | 169 if (cache_state_ != CacheReady) { |
165 // If the backend hasn't yet initialized, try the request again later. | 170 // If the backend hasn't yet initialized, try the request again later. |
166 BrowserThread::PostDelayedTask(BrowserThread::IO, | 171 BrowserThread::PostDelayedTask(BrowserThread::IO, |
167 FROM_HERE, | 172 FROM_HERE, |
168 base::Bind(&PnaclHost::GetNexeFd, | 173 base::Bind(&PnaclHost::GetNexeFd, |
169 weak_factory_.GetWeakPtr(), | 174 weak_factory_.GetWeakPtr(), |
170 render_process_id, | 175 render_process_id, |
171 render_view_id, | 176 render_view_id, |
172 pp_instance, | 177 pp_instance, |
173 is_incognito, | 178 is_incognito, |
174 cache_info, | 179 cache_info, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 // by PnaclTranslationCache and now belongs to PnaclHost. | 228 // by PnaclTranslationCache and now belongs to PnaclHost. |
224 // (Bound callbacks must re-lookup the TranslationID because the translation | 229 // (Bound callbacks must re-lookup the TranslationID because the translation |
225 // could be cancelled before they get called). | 230 // could be cancelled before they get called). |
226 void PnaclHost::OnCacheQueryReturn( | 231 void PnaclHost::OnCacheQueryReturn( |
227 const TranslationID& id, | 232 const TranslationID& id, |
228 int net_error, | 233 int net_error, |
229 scoped_refptr<net::DrainableIOBuffer> buffer) { | 234 scoped_refptr<net::DrainableIOBuffer> buffer) { |
230 DCHECK(thread_checker_.CalledOnValidThread()); | 235 DCHECK(thread_checker_.CalledOnValidThread()); |
231 PendingTranslationMap::iterator entry(pending_translations_.find(id)); | 236 PendingTranslationMap::iterator entry(pending_translations_.find(id)); |
232 if (entry == pending_translations_.end()) { | 237 if (entry == pending_translations_.end()) { |
| 238 LOG(ERROR) << "PnaclHost::OnCacheQueryReturn: id not found"; |
233 return; | 239 return; |
234 } | 240 } |
235 PendingTranslation* pt = &entry->second; | 241 PendingTranslation* pt = &entry->second; |
236 pt->got_cache_reply = true; | 242 pt->got_cache_reply = true; |
237 pt->got_cache_hit = (net_error == net::OK); | 243 pt->got_cache_hit = (net_error == net::OK); |
238 if (pt->got_cache_hit) | 244 if (pt->got_cache_hit) |
239 pt->nexe_read_buffer = buffer; | 245 pt->nexe_read_buffer = buffer; |
240 CheckCacheQueryReady(entry); | 246 CheckCacheQueryReady(entry); |
241 } | 247 } |
242 | 248 |
243 // Callback from temp file creation. |id| is bound from | 249 // Callback from temp file creation. |id| is bound from |
244 // SendCacheQueryAndTempFileRequest, and fd is the created file descriptor. | 250 // SendCacheQueryAndTempFileRequest, and fd is the created file descriptor. |
245 // If there was an error, fd is kInvalidPlatformFileValue. | 251 // If there was an error, fd is kInvalidPlatformFileValue. |
246 // (Bound callbacks must re-lookup the TranslationID because the translation | 252 // (Bound callbacks must re-lookup the TranslationID because the translation |
247 // could be cancelled before they get called). | 253 // could be cancelled before they get called). |
248 void PnaclHost::OnTempFileReturn(const TranslationID& id, | 254 void PnaclHost::OnTempFileReturn(const TranslationID& id, |
249 base::PlatformFile fd) { | 255 base::PlatformFile fd) { |
250 DCHECK(thread_checker_.CalledOnValidThread()); | 256 DCHECK(thread_checker_.CalledOnValidThread()); |
251 PendingTranslationMap::iterator entry(pending_translations_.find(id)); | 257 PendingTranslationMap::iterator entry(pending_translations_.find(id)); |
252 if (entry == pending_translations_.end()) { | 258 if (entry == pending_translations_.end()) { |
253 // The renderer may have signaled an error or closed while the temp | 259 // The renderer may have signaled an error or closed while the temp |
254 // file was being created. | 260 // file was being created. |
| 261 LOG(ERROR) << "PnaclHost::OnTempFileReturn: id not found"; |
255 BrowserThread::PostBlockingPoolTask( | 262 BrowserThread::PostBlockingPoolTask( |
256 FROM_HERE, base::Bind(base::IgnoreResult(base::ClosePlatformFile), fd)); | 263 FROM_HERE, base::Bind(base::IgnoreResult(base::ClosePlatformFile), fd)); |
257 return; | 264 return; |
258 } | 265 } |
259 if (fd == base::kInvalidPlatformFileValue) { | 266 if (fd == base::kInvalidPlatformFileValue) { |
| 267 // This translation will fail, but we need to retry any translation |
| 268 // waiting for its result. |
| 269 LOG(ERROR) << "PnaclHost::OnTempFileReturn: temp file creation failed"; |
260 std::string key(entry->second.cache_key); | 270 std::string key(entry->second.cache_key); |
261 bool is_incognito = entry->second.is_incognito; | 271 bool is_incognito = entry->second.is_incognito; |
262 entry->second.callback.Run(fd, false); | 272 entry->second.callback.Run(fd, false); |
263 pending_translations_.erase(entry); | 273 pending_translations_.erase(entry); |
264 // No translations will be blocked waiting for an incongnito translation | 274 // No translations will be waiting for an incongnito translation |
265 if (!is_incognito) | 275 if (!is_incognito) |
266 RequeryMatchingTranslations(key); | 276 RequeryMatchingTranslations(key); |
267 return; | 277 return; |
268 } | 278 } |
269 PendingTranslation* pt = &entry->second; | 279 PendingTranslation* pt = &entry->second; |
270 pt->got_nexe_fd = true; | 280 pt->got_nexe_fd = true; |
271 pt->nexe_fd = fd; | 281 pt->nexe_fd = fd; |
272 CheckCacheQueryReady(entry); | 282 CheckCacheQueryReady(entry); |
273 } | 283 } |
274 | 284 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 338 |
329 // On error, just return a null refptr. | 339 // On error, just return a null refptr. |
330 // static | 340 // static |
331 scoped_refptr<net::DrainableIOBuffer> PnaclHost::CopyFileToBuffer( | 341 scoped_refptr<net::DrainableIOBuffer> PnaclHost::CopyFileToBuffer( |
332 base::PlatformFile fd) { | 342 base::PlatformFile fd) { |
333 base::PlatformFileInfo info; | 343 base::PlatformFileInfo info; |
334 scoped_refptr<net::DrainableIOBuffer> buffer; | 344 scoped_refptr<net::DrainableIOBuffer> buffer; |
335 bool error = false; | 345 bool error = false; |
336 if (!base::GetPlatformFileInfo(fd, &info) || | 346 if (!base::GetPlatformFileInfo(fd, &info) || |
337 info.size >= std::numeric_limits<int>::max()) { | 347 info.size >= std::numeric_limits<int>::max()) { |
| 348 LOG(ERROR) << "PnaclHost: GetPlatformFileInfo failed"; |
338 error = true; | 349 error = true; |
339 } else { | 350 } else { |
340 buffer = new net::DrainableIOBuffer( | 351 buffer = new net::DrainableIOBuffer( |
341 new net::IOBuffer(static_cast<int>(info.size)), info.size); | 352 new net::IOBuffer(static_cast<int>(info.size)), info.size); |
342 if (base::ReadPlatformFile(fd, 0, buffer->data(), buffer->size()) != | 353 if (base::ReadPlatformFile(fd, 0, buffer->data(), buffer->size()) != |
343 info.size) | 354 info.size) { |
| 355 LOG(ERROR) << "PnaclHost: CopyFileToBuffer write failed"; |
344 error = true; | 356 error = true; |
| 357 } |
345 } | 358 } |
346 if (error) { | 359 if (error) { |
347 buffer = NULL; | 360 buffer = NULL; |
348 } | 361 } |
349 base::ClosePlatformFile(fd); | 362 base::ClosePlatformFile(fd); |
350 return buffer; | 363 return buffer; |
351 } | 364 } |
352 | 365 |
353 // Called by the renderer in the miss path to report a finished translation | 366 // Called by the renderer in the miss path to report a finished translation |
354 void PnaclHost::TranslationFinished(int render_process_id, | 367 void PnaclHost::TranslationFinished(int render_process_id, |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 end_time, | 566 end_time, |
554 base::Bind(&PnaclHost::OnEntriesDoomed, callback)); | 567 base::Bind(&PnaclHost::OnEntriesDoomed, callback)); |
555 if (rv != net::ERR_IO_PENDING) | 568 if (rv != net::ERR_IO_PENDING) |
556 OnEntriesDoomed(callback, rv); | 569 OnEntriesDoomed(callback, rv); |
557 } | 570 } |
558 | 571 |
559 // static | 572 // static |
560 void PnaclHost::OnEntriesDoomed(const base::Closure& callback, int net_error) { | 573 void PnaclHost::OnEntriesDoomed(const base::Closure& callback, int net_error) { |
561 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback); | 574 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback); |
562 } | 575 } |
OLD | NEW |