Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: trunk/src/chrome/browser/nacl_host/pnacl_translation_cache.cc

Issue 16279009: Revert 204354 "Add read support to PNaClTranslationCache" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_translation_cache.h" 5 #include "chrome/browser/nacl_host/pnacl_translation_cache.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 15 matching lines...) Expand all
26 26
27 } // namespace 27 } // namespace
28 28
29 namespace pnacl_cache { 29 namespace pnacl_cache {
30 // These are in pnacl_cache namespace instead of static so they can be used 30 // These are in pnacl_cache namespace instead of static so they can be used
31 // by the unit test. 31 // by the unit test.
32 const int kMaxDiskCacheSize = 1000 * 1024 * 1024; 32 const int kMaxDiskCacheSize = 1000 * 1024 * 1024;
33 const int kMaxMemCacheSize = 100 * 1024 * 1024; 33 const int kMaxMemCacheSize = 100 * 1024 * 1024;
34 34
35 ////////////////////////////////////////////////////////////////////// 35 //////////////////////////////////////////////////////////////////////
36 // Handle Reading/Writing to Cache. 36 // Handle Storing to Cache.
37 37
38 // PNaClTranslationCacheEntry is a shim that provides storage for the 38 // PNaClTranslationCacheWriteEntry is a shim that provides storage for the
39 // 'key' and 'data' strings as the disk_cache is performing various async 39 // 'key' and 'data' strings as the disk_cache is performing various async
40 // operations. It also tracks the open disk_cache::Entry 40 // operations. It also tracks the open disk_cache::Entry
41 // and ensures that the entry is closed. 41 // and ensures that the entry is closed.
42 class PNaClTranslationCacheEntry 42 class PNaClTranslationCacheWriteEntry
43 : public base::RefCounted<PNaClTranslationCacheEntry> { 43 : public base::RefCounted<PNaClTranslationCacheWriteEntry> {
44 public: 44 public:
45 PNaClTranslationCacheEntry(base::WeakPtr<PNaClTranslationCache> cache, 45 PNaClTranslationCacheWriteEntry(base::WeakPtr<PNaClTranslationCache> cache,
46 const std::string& key, 46 const std::string& key,
47 std::string* read_nexe, 47 const std::string& nexe,
48 const std::string& write_nexe, 48 const net::CompletionCallback& callback);
49 const CompletionCallback& callback,
50 bool is_read);
51 void Start();
52 49
53 // Writes: --- 50 void Cache();
51
52 // ---
54 // v | 53 // v |
55 // Start -> Open Existing --------------> Write ---> Close 54 // Cache -> Open Existing --------------> Write ---> Close
56 // \ ^ 55 // \ ^
57 // \ / 56 // \ /
58 // --> Create -- 57 // --> Create --
59 // Reads:
60 // Start -> Open --------Read ----> Close
61 // | ^
62 // |__|
63 enum CacheStep { 58 enum CacheStep {
64 UNINITIALIZED, 59 UNINITIALIZED,
65 OPEN_ENTRY, 60 OPEN_ENTRY,
66 CREATE_ENTRY, 61 CREATE_ENTRY,
67 TRANSFER_ENTRY, 62 WRITE_ENTRY,
68 CLOSE_ENTRY 63 CLOSE_ENTRY
69 }; 64 };
70 65
71 private: 66 private:
72 friend class base::RefCounted<PNaClTranslationCacheEntry>; 67 friend class base::RefCounted<PNaClTranslationCacheWriteEntry>;
73 ~PNaClTranslationCacheEntry(); 68 ~PNaClTranslationCacheWriteEntry();
74 69
75 // Try to open an existing entry in the backend 70 void CreateEntry();
71
76 void OpenEntry(); 72 void OpenEntry();
77 // Create a new entry in the backend (for writes) 73
78 void CreateEntry(); 74 void WriteEntry(int bytes_to_skip);
79 // Write |len| bytes to the backend, starting at |offset| 75
80 void WriteEntry(int offset, int len);
81 // Read |len| bytes from the backend, starting at |offset|
82 void ReadEntry(int offset, int len);
83 // If there was an error, doom the entry. Then post a task to the IO
84 // thread to close (and delete) it.
85 void CloseEntry(int rv); 76 void CloseEntry(int rv);
86 // Call the user callback, and signal to the cache to delete this. 77
87 void Finish(int rv);
88 // Used as the callback for all operations to the backend. Handle state
89 // transitions, track bytes transferred, and call the other helper methods.
90 void DispatchNext(int rv); 78 void DispatchNext(int rv);
91 // Get the total transfer size. For reads, must be called after the backend
92 // entry has been opened.
93 int GetTransferSize();
94 79
95 base::WeakPtr<PNaClTranslationCache> cache_; 80 base::WeakPtr<PNaClTranslationCache> cache_;
96 81
97 std::string key_; 82 std::string key_;
98 std::string* read_nexe_; 83 std::string nexe_;
99 std::string write_nexe_;
100 disk_cache::Entry* entry_; 84 disk_cache::Entry* entry_;
101 CacheStep step_; 85 CacheStep step_;
102 bool is_read_;
103 int bytes_transferred_;
104 int bytes_to_transfer_;
105 scoped_refptr<net::IOBufferWithSize> read_buf_;
106 CompletionCallback finish_callback_; 86 CompletionCallback finish_callback_;
107 base::ThreadChecker thread_checker_; 87 base::ThreadChecker thread_checker_;
108 DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCacheEntry); 88 DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCacheWriteEntry);
109 }; 89 };
110 90
111 PNaClTranslationCacheEntry::PNaClTranslationCacheEntry( 91 PNaClTranslationCacheWriteEntry::PNaClTranslationCacheWriteEntry(
112 base::WeakPtr<PNaClTranslationCache> cache, 92 base::WeakPtr<PNaClTranslationCache> cache,
113 const std::string& key, 93 const std::string& key,
114 std::string* read_nexe, 94 const std::string& nexe,
115 const std::string& write_nexe, 95 const net::CompletionCallback& callback)
116 const CompletionCallback& callback,
117 bool is_read)
118 : cache_(cache), 96 : cache_(cache),
119 key_(key), 97 key_(key),
120 read_nexe_(read_nexe), 98 nexe_(nexe),
121 write_nexe_(write_nexe),
122 entry_(NULL), 99 entry_(NULL),
123 step_(UNINITIALIZED), 100 step_(UNINITIALIZED),
124 is_read_(is_read),
125 bytes_transferred_(0),
126 bytes_to_transfer_(-1),
127 finish_callback_(callback) {} 101 finish_callback_(callback) {}
128 102
129 PNaClTranslationCacheEntry::~PNaClTranslationCacheEntry() { 103 PNaClTranslationCacheWriteEntry::~PNaClTranslationCacheWriteEntry() {
130 // Ensure we have called the user's callback 104 if (entry_)
131 DCHECK(finish_callback_.is_null()); 105 BrowserThread::PostTask(
106 BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_));
132 } 107 }
133 108
134 void PNaClTranslationCacheEntry::Start() { 109 void PNaClTranslationCacheWriteEntry::Cache() {
135 DCHECK(thread_checker_.CalledOnValidThread()); 110 DCHECK(thread_checker_.CalledOnValidThread());
136 step_ = OPEN_ENTRY; 111 step_ = OPEN_ENTRY;
137 OpenEntry(); 112 OpenEntry();
138 } 113 }
139 114
140 // OpenEntry, CreateEntry, WriteEntry, ReadEntry and CloseEntry are only called 115 // OpenEntry, CreateEntry, WriteEntry, and CloseEntry are only called from
141 // from DispatchNext, so they know that cache_ is still valid. 116 // DispatchNext, so they know that cache_ is still valid.
142 void PNaClTranslationCacheEntry::OpenEntry() { 117 void PNaClTranslationCacheWriteEntry::OpenEntry() {
143 int rv = cache_->backend() 118 int rv = cache_->backend()->OpenEntry(
144 ->OpenEntry(key_, 119 key_,
145 &entry_, 120 &entry_,
146 base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this)); 121 base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this));
147 if (rv != net::ERR_IO_PENDING) 122 if (rv != net::ERR_IO_PENDING)
148 DispatchNext(rv); 123 DispatchNext(rv);
149 } 124 }
150 125
151 void PNaClTranslationCacheEntry::CreateEntry() { 126 void PNaClTranslationCacheWriteEntry::CreateEntry() {
152 int rv = cache_->backend()->CreateEntry( 127 int rv = cache_->backend()->CreateEntry(
153 key_, 128 key_,
154 &entry_, 129 &entry_,
155 base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this)); 130 base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this));
156 if (rv != net::ERR_IO_PENDING) 131 if (rv != net::ERR_IO_PENDING)
157 DispatchNext(rv); 132 DispatchNext(rv);
158 } 133 }
159 134
160 void PNaClTranslationCacheEntry::WriteEntry(int offset, int len) { 135 void PNaClTranslationCacheWriteEntry::WriteEntry(int bytes_to_skip) {
161 scoped_refptr<net::StringIOBuffer> io_buf = 136 nexe_ = nexe_.substr(bytes_to_skip);
162 new net::StringIOBuffer(write_nexe_.substr(offset, len)); 137 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(nexe_);
163 int rv = entry_->WriteData( 138 int rv = entry_->WriteData(
164 1, 139 1,
165 offset, 140 0,
166 io_buf, 141 io_buf,
167 len, 142 nexe_.length(),
168 base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this), 143 base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this),
169 false); 144 false);
170 if (rv != net::ERR_IO_PENDING) 145 if (rv != net::ERR_IO_PENDING)
171 DispatchNext(rv); 146 DispatchNext(rv);
172 } 147 }
173 148
174 void PNaClTranslationCacheEntry::ReadEntry(int offset, int len) { 149 void PNaClTranslationCacheWriteEntry::CloseEntry(int rv) {
175 read_buf_ = new net::IOBufferWithSize(len);
176 int rv = entry_->ReadData(
177 1,
178 offset,
179 read_buf_,
180 len,
181 base::Bind(&PNaClTranslationCacheEntry::DispatchNext, this));
182 if (rv != net::ERR_IO_PENDING)
183 DispatchNext(rv);
184 }
185
186 int PNaClTranslationCacheEntry::GetTransferSize() {
187 if (is_read_) {
188 DCHECK(entry_);
189 return entry_->GetDataSize(1);
190 }
191 return write_nexe_.size();
192 }
193
194 void PNaClTranslationCacheEntry::CloseEntry(int rv) {
195 DCHECK(entry_);
196 if (rv < 0) 150 if (rv < 0)
197 entry_->Doom(); 151 entry_->Doom();
198 BrowserThread::PostTask(
199 BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_));
200 Finish(rv);
201 }
202
203 void PNaClTranslationCacheEntry::Finish(int rv) {
204 if (!finish_callback_.is_null()) { 152 if (!finish_callback_.is_null()) {
205 finish_callback_.Run(rv); 153 finish_callback_.Run(rv);
206 finish_callback_.Reset(); 154 finish_callback_.Reset();
207 } 155 }
208 cache_->OpComplete(this); 156 cache_->WriteComplete(this);
209 } 157 }
210 158
211 void PNaClTranslationCacheEntry::DispatchNext(int rv) { 159 void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
212 DCHECK(thread_checker_.CalledOnValidThread()); 160 DCHECK(thread_checker_.CalledOnValidThread());
213 if (!cache_.get()) 161 if (!cache_.get())
214 return; 162 return;
215 163
216 switch (step_) { 164 switch (step_) {
217 case UNINITIALIZED: 165 case UNINITIALIZED:
218 LOG(ERROR) << "Unexpected step in DispatchNext"; 166 LOG(ERROR) << "Unexpected step in DispatchNext";
219 break; 167 break;
220 168
221 case OPEN_ENTRY: 169 case OPEN_ENTRY:
222 if (rv == net::OK) { 170 if (rv == net::OK) {
223 step_ = TRANSFER_ENTRY; 171 step_ = WRITE_ENTRY;
224 bytes_to_transfer_ = GetTransferSize(); 172 WriteEntry(0);
225 is_read_ ? ReadEntry(0, bytes_to_transfer_)
226 : WriteEntry(0, bytes_to_transfer_);
227 } else { 173 } else {
228 if (is_read_) {
229 // Just a cache miss, not necessarily an error.
230 entry_ = NULL;
231 Finish(rv);
232 break;
233 }
234 step_ = CREATE_ENTRY; 174 step_ = CREATE_ENTRY;
235 CreateEntry(); 175 CreateEntry();
236 } 176 }
237 break; 177 break;
238 178
239 case CREATE_ENTRY: 179 case CREATE_ENTRY:
240 if (rv == net::OK) { 180 if (rv == net::OK) {
241 step_ = TRANSFER_ENTRY; 181 step_ = WRITE_ENTRY;
242 bytes_to_transfer_ = GetTransferSize(); 182 WriteEntry(0);
243 WriteEntry(bytes_transferred_, bytes_to_transfer_ - bytes_transferred_);
244 } else { 183 } else {
245 LOG(ERROR) << "Failed to Create a PNaCl Translation Cache Entry"; 184 LOG(ERROR) << "Failed to Open/Create a PNaCl Translation Cache Entry";
246 Finish(rv); 185 CloseEntry(rv);
247 } 186 }
248 break; 187 break;
249 188
250 case TRANSFER_ENTRY: 189 case WRITE_ENTRY:
251 if (rv < 0) { 190 if (rv < 0) {
252 // We do not call DispatchNext directly if WriteEntry/ReadEntry returns 191 // We do not call DispatchNext directly if WriteEntry returns
253 // ERR_IO_PENDING, and the callback should not return that value either. 192 // ERR_IO_PENDING, and the callback should not return that value either.
254 LOG(ERROR) 193 LOG(ERROR)
255 << "Failed to complete write to PNaCl Translation Cache Entry: " 194 << "Failed to complete write to PNaCl Translation Cache Entry: "
256 << rv; 195 << rv;
257 step_ = CLOSE_ENTRY; 196 step_ = CLOSE_ENTRY;
258 CloseEntry(rv); 197 CloseEntry(rv);
259 break; 198 break;
260 } else if (rv > 0) {
261 // For reads, copy the data that was just returned
262 if (is_read_)
263 read_nexe_->append(read_buf_->data(), rv);
264 bytes_transferred_ += rv;
265 if (bytes_transferred_ < bytes_to_transfer_) {
266 int len = bytes_to_transfer_ - bytes_transferred_;
267 is_read_ ? ReadEntry(bytes_transferred_, len)
268 : WriteEntry(bytes_transferred_, len);
269 break;
270 }
271 } 199 }
272 // rv == 0 or we fell through (i.e. we have transferred all the bytes) 200 if (rv == 0) {
273 step_ = CLOSE_ENTRY; 201 step_ = CLOSE_ENTRY;
274 CloseEntry(0); 202 CloseEntry(rv);
203 break;
204 }
205 // rv bytes were written; call WriteEntry again to skip them and try to
206 // write the rest.
207 WriteEntry(rv);
275 break; 208 break;
276 209
277 case CLOSE_ENTRY: 210 case CLOSE_ENTRY:
278 step_ = UNINITIALIZED; 211 step_ = UNINITIALIZED;
279 break; 212 break;
280 } 213 }
281 } 214 }
282 215
283 ////////////////////////////////////////////////////////////////////// 216 //////////////////////////////////////////////////////////////////////
284 void PNaClTranslationCache::OpComplete(PNaClTranslationCacheEntry* entry) { 217 void PNaClTranslationCache::WriteComplete(
285 open_entries_.erase(entry); 218 PNaClTranslationCacheWriteEntry* entry) {
219 write_entries_.erase(entry);
286 } 220 }
287 221
288 ////////////////////////////////////////////////////////////////////// 222 //////////////////////////////////////////////////////////////////////
289 // Construction and cache backend initialization 223 // Construction and cache backend initialization
290 PNaClTranslationCache::PNaClTranslationCache() 224 PNaClTranslationCache::PNaClTranslationCache()
291 : disk_cache_(NULL), in_memory_(false) {} 225 : disk_cache_(NULL), in_memory_(false) {}
292 226
293 PNaClTranslationCache::~PNaClTranslationCache() { delete disk_cache_; } 227 PNaClTranslationCache::~PNaClTranslationCache() {
228 delete disk_cache_;
229 }
294 230
295 int PNaClTranslationCache::InitWithDiskBackend( 231 int PNaClTranslationCache::InitWithDiskBackend(
296 const base::FilePath& cache_dir, 232 const base::FilePath& cache_dir,
297 int cache_size, 233 int cache_size,
298 const CompletionCallback& callback) { 234 const net::CompletionCallback& callback) {
299 return Init(net::DISK_CACHE, cache_dir, cache_size, callback); 235 return Init(net::DISK_CACHE, cache_dir, cache_size, callback);
300 } 236 }
301 237
302 int PNaClTranslationCache::InitWithMemBackend( 238 int PNaClTranslationCache::InitWithMemBackend(
303 int cache_size, 239 int cache_size,
304 const CompletionCallback& callback) { 240 const net::CompletionCallback& callback) {
305 return Init(net::MEMORY_CACHE, base::FilePath(), cache_size, callback); 241 return Init(net::MEMORY_CACHE, base::FilePath(), cache_size, callback);
306 } 242 }
307 243
308 int PNaClTranslationCache::Init(net::CacheType cache_type, 244 int PNaClTranslationCache::Init(net::CacheType cache_type,
309 const base::FilePath& cache_dir, 245 const base::FilePath& cache_dir,
310 int cache_size, 246 int cache_size,
311 const CompletionCallback& callback) { 247 const net::CompletionCallback& callback) {
312 int rv = disk_cache::CreateCacheBackend( 248 int rv = disk_cache::CreateCacheBackend(
313 cache_type, 249 cache_type,
314 net::CACHE_BACKEND_DEFAULT, 250 net::CACHE_BACKEND_DEFAULT,
315 cache_dir, 251 cache_dir,
316 cache_size, 252 cache_size,
317 true /* force_initialize */, 253 true /* force_initialize */,
318 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE), 254 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE),
319 NULL, /* dummy net log */ 255 NULL, /* dummy net log */
320 &disk_cache_, 256 &disk_cache_,
321 base::Bind(&PNaClTranslationCache::OnCreateBackendComplete, AsWeakPtr())); 257 base::Bind(&PNaClTranslationCache::OnCreateBackendComplete, AsWeakPtr()));
322 init_callback_ = callback; 258 init_callback_ = callback;
323 if (rv != net::ERR_IO_PENDING) { 259 if (rv != net::ERR_IO_PENDING) {
324 OnCreateBackendComplete(rv); 260 OnCreateBackendComplete(rv);
325 } 261 }
326 return rv; 262 return rv;
327 } 263 }
328 264
329 void PNaClTranslationCache::OnCreateBackendComplete(int rv) { 265 void PNaClTranslationCache::OnCreateBackendComplete(int rv) {
330 // Invoke our client's callback function. 266 // Invoke our client's callback function.
331 if (!init_callback_.is_null()) { 267 if (!init_callback_.is_null()) {
332 init_callback_.Run(rv); 268 init_callback_.Run(rv);
333 init_callback_.Reset(); 269 init_callback_.Reset();
334 } 270 }
335 } 271 }
336 272
337 ////////////////////////////////////////////////////////////////////// 273 //////////////////////////////////////////////////////////////////////
338 // High-level API 274 // High-level API
339 275
276 // TODO(dschuff): Surely there must be a way to just create a null callback?
277 static void NullCallback(int ignored) {}
278
340 void PNaClTranslationCache::StoreNexe(const std::string& key, 279 void PNaClTranslationCache::StoreNexe(const std::string& key,
341 const std::string& nexe) { 280 const std::string& nexe) {
342 StoreNexe(key, nexe, CompletionCallback()); 281 StoreNexe(key, nexe, base::Bind(NullCallback));
343 } 282 }
344 283
345 void PNaClTranslationCache::StoreNexe(const std::string& key, 284 void PNaClTranslationCache::StoreNexe(const std::string& key,
346 const std::string& nexe, 285 const std::string& nexe,
347 const CompletionCallback& callback) { 286 const net::CompletionCallback& callback) {
348 PNaClTranslationCacheEntry* entry = new PNaClTranslationCacheEntry( 287 PNaClTranslationCacheWriteEntry* entry =
349 AsWeakPtr(), key, NULL, nexe, callback, false); 288 new PNaClTranslationCacheWriteEntry(AsWeakPtr(), key, nexe, callback);
350 open_entries_[entry] = entry; 289 write_entries_[entry] = entry;
351 entry->Start(); 290 entry->Cache();
352 } 291 }
353 292
354 void PNaClTranslationCache::GetNexe(const std::string& key, 293 int PNaClTranslationCache::GetNexe(const std::string& key,
355 std::string* nexe, 294 std::string* nexe,
356 const CompletionCallback& callback) { 295 const net::CompletionCallback& callback) {
357 PNaClTranslationCacheEntry* entry = new PNaClTranslationCacheEntry( 296 // TODO(dschuff): Actually find the entry, and do the right thing.
358 AsWeakPtr(), key, nexe, std::string(), callback, true); 297 // Shader cache ended up making a separate ReadHelper, analogous
359 open_entries_[entry] = entry; 298 // to the PNaClTranslationCacheWriteEntry.
360 entry->Start(); 299 return net::OK;
361 } 300 }
362 301
363 int PNaClTranslationCache::InitCache(const base::FilePath& cache_directory, 302 int PNaClTranslationCache::InitCache(const base::FilePath& cache_directory,
364 bool in_memory, 303 bool in_memory,
365 const CompletionCallback& callback) { 304 const net::CompletionCallback& callback) {
366 int rv; 305 int rv;
367 in_memory_ = in_memory; 306 in_memory_ = in_memory;
368 if (in_memory_) { 307 if (in_memory_) {
369 rv = InitWithMemBackend(kMaxMemCacheSize, callback); 308 rv = InitWithMemBackend(kMaxMemCacheSize, callback);
370 } else { 309 } else {
371 rv = InitWithDiskBackend(cache_directory.Append(kDiskCacheDirectoryName), 310 rv = InitWithDiskBackend(cache_directory.Append(kDiskCacheDirectoryName),
372 kMaxDiskCacheSize, 311 kMaxDiskCacheSize,
373 callback); 312 callback);
374 } 313 }
375 314
376 return rv; 315 return rv;
377 } 316 }
378 317
379 int PNaClTranslationCache::Size() { 318 int PNaClTranslationCache::Size() {
380 if (!disk_cache_) 319 if (!disk_cache_)
381 return -1; 320 return -1;
382 return disk_cache_->GetEntryCount(); 321 return disk_cache_->GetEntryCount();
383 } 322 }
384 323
385 } // namespace nacl_cache 324 } // namespace nacl_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698