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

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

Issue 16232011: Add PNaCl translation cache based on Chrome disk_cache (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win build, disable_nacl=1, clang build 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
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/nacl_host/pnacl_translation_cache.h"
6
7 #include <string>
8
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/time.h"
jvoung (off chromium) 2013/05/31 01:12:14 no need for base/time.h if you remove the start_ti
Derek Schuff 2013/05/31 23:15:31 Done.
12 #include "chrome/common/chrome_paths.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/disk_cache/disk_cache.h"
17
18 using content::BrowserThread;
19
20 static const base::FilePath::CharType kDiskCacheDirectoryName[] =
21 FILE_PATH_LITERAL("PNaClTranslationCache");
22
23 namespace {
24
25 void CloseDiskCacheEntry(disk_cache::Entry* entry) { entry->Close(); }
26
27 } // namespace
28
29 namespace pnacl_cache {
30 // These are in pnacl_cache namespace instead of static so they can be used
31 // by the unit test.
32 const int kMaxDiskCacheSize = 1000 * 1024 * 1024;
33 const int kMaxMemCacheSize = 100 * 1024 * 1024;
34
35 //////////////////////////////////////////////////////////////////////
36 // Handle Storing to Cache.
37
38 // PNaClTranslationCacheWriteEntry is a shim that provides storage for the
39 // 'key' and 'data' strings as the disk_cache is performing various async
40 // operations. It also tracks the open disk_cache::Entry
41 // and ensures that the entry is closed.
42 class PNaClTranslationCacheWriteEntry
43 : public base::RefCounted<PNaClTranslationCacheWriteEntry> {
44 public:
45 PNaClTranslationCacheWriteEntry(base::WeakPtr<PNaClTranslationCache> cache,
46 const std::string& key,
47 const std::string& nexe,
48 const net::CompletionCallback& callback);
49
50 void Cache();
51
52 // ---
53 // v |
54 // Cache -> Open Existing --------------> Write ---> Close
55 // \ ^
56 // \ /
57 // --> Create --
58 enum CacheStep {
59 UNINITIALIZED,
60 OPEN_ENTRY,
61 CREATE_ENTRY,
62 WRITE_ENTRY,
63 CLOSE_ENTRY
64 };
65
66 private:
67 friend class base::RefCounted<PNaClTranslationCacheWriteEntry>;
68 ~PNaClTranslationCacheWriteEntry();
69
70 void CreateEntry();
71
72 void OpenEntry();
73
74 void WriteEntry(int bytes_to_skip);
75
76 void CloseEntry(int rv);
77
78 void DispatchNext(int rv);
79
80 base::WeakPtr<PNaClTranslationCache> cache_;
81
82 base::Time start_time_;
jvoung (off chromium) 2013/05/31 01:12:14 You could remove start_time_, since this was just
Derek Schuff 2013/05/31 23:15:31 Done.
83 std::string key_;
84 std::string nexe_;
85 disk_cache::Entry* entry_;
86 CacheStep step_;
87 CompletionCallback finish_callback_;
88 DISALLOW_COPY_AND_ASSIGN(PNaClTranslationCacheWriteEntry);
89 };
90
91 PNaClTranslationCacheWriteEntry::PNaClTranslationCacheWriteEntry(
92 base::WeakPtr<PNaClTranslationCache> cache,
93 const std::string& key,
94 const std::string& nexe,
95 const net::CompletionCallback& callback)
96 : cache_(cache),
97 key_(key),
98 nexe_(nexe),
99 entry_(NULL),
100 step_(UNINITIALIZED),
101 finish_callback_(callback) {}
102
103 PNaClTranslationCacheWriteEntry::~PNaClTranslationCacheWriteEntry() {
104 if (entry_)
105 BrowserThread::PostTask(
106 BrowserThread::IO, FROM_HERE, base::Bind(&CloseDiskCacheEntry, entry_));
107 }
108
109 void PNaClTranslationCacheWriteEntry::Cache() {
110 start_time_ = base::Time::Now();
111 OpenEntry();
112 }
113
114 void PNaClTranslationCacheWriteEntry::OpenEntry() {
115 if (!cache_)
116 return;
117
118 step_ = OPEN_ENTRY;
jvoung (off chromium) 2013/05/31 01:12:14 could move the step_ setting outside of this and i
Derek Schuff 2013/05/31 23:15:31 Done.
119 int rv = cache_->backend()->OpenEntry(
120 key_,
121 &entry_,
122 base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this));
123 if (rv != net::ERR_IO_PENDING)
124 DispatchNext(rv);
125 }
126
127 void PNaClTranslationCacheWriteEntry::CreateEntry() {
128 if (!cache_)
129 return;
130
131 step_ = CREATE_ENTRY;
jvoung (off chromium) 2013/05/31 01:12:14 step is already set by the DispatchNext.
Derek Schuff 2013/05/31 23:15:31 Done.
132 int rv = cache_->backend()->CreateEntry(
133 key_,
134 &entry_,
135 base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this));
136 if (rv != net::ERR_IO_PENDING)
137 DispatchNext(rv);
138 }
139
140 void PNaClTranslationCacheWriteEntry::WriteEntry(int bytes_to_skip) {
141 if (!cache_)
142 return;
143
144 nexe_ = nexe_.substr(bytes_to_skip);
145 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(nexe_);
146 int rv = entry_->WriteData(
147 1,
148 0,
149 io_buf,
150 nexe_.length(),
151 base::Bind(&PNaClTranslationCacheWriteEntry::DispatchNext, this),
152 false);
153 if (rv != net::ERR_IO_PENDING)
154 DispatchNext(rv);
155 }
156
157 void PNaClTranslationCacheWriteEntry::CloseEntry(int rv) {
158 if (!cache_)
159 return;
160
161 if (!finish_callback_.is_null()) {
162 finish_callback_.Run(rv);
163 finish_callback_.Reset();
164 }
165 cache_->WriteComplete(this);
166 }
167
168 void PNaClTranslationCacheWriteEntry::DispatchNext(int rv) {
169 if (!cache_)
170 return;
171
172 switch (step_) {
173 case UNINITIALIZED:
174 LOG(ERROR) << "Unexpected step in DispatchNext";
175 break;
176
177 case OPEN_ENTRY:
178 if (rv == net::OK) {
179 step_ = WRITE_ENTRY;
180 WriteEntry(0);
181 } else {
182 step_ = CREATE_ENTRY;
183 CreateEntry();
184 }
185 break;
186
187 case CREATE_ENTRY:
188 if (rv == net::OK) {
189 step_ = WRITE_ENTRY;
190 WriteEntry(0);
191 } else {
192 LOG(ERROR) << "Failed to Open/Create a PNaCl Translation Cache Entry";
193 CloseEntry(rv);
194 }
195 break;
196
197 case WRITE_ENTRY:
198 if (rv == net::ERR_IO_PENDING) {
199 return;
200 }
201 if (rv < 0) {
202 LOG(ERROR)
203 << "Failed to complete write to PNaCl Translation Cache Entry: "
204 << rv;
205 CloseEntry(rv);
jvoung (off chromium) 2013/05/31 01:12:14 could set step_ to CLOSE_ENTRY before these calls,
Derek Schuff 2013/05/31 23:15:31 Done.
206 break;
207 }
208 if (rv == 0) {
209 step_ = CLOSE_ENTRY;
210 CloseEntry(rv);
211 break;
212 }
213 WriteEntry(rv);
214 break;
215
216 case CLOSE_ENTRY:
217 step_ = UNINITIALIZED;
218 break;
219 }
220 }
221
222 //////////////////////////////////////////////////////////////////////
223 void PNaClTranslationCache::WriteComplete(
224 PNaClTranslationCacheWriteEntry* entry) {
225 write_entries_.erase(entry);
226 }
227
228 //////////////////////////////////////////////////////////////////////
229 // Construction and cache backend initialization
230 PNaClTranslationCache::PNaClTranslationCache()
231 : disk_cache_(NULL), in_memory_(false) {}
232
233 PNaClTranslationCache::~PNaClTranslationCache() {}
234
235 int PNaClTranslationCache::InitWithDiskBackend(
236 const base::FilePath& cache_dir,
237 int cache_size,
238 const net::CompletionCallback& callback) {
239 return Init(net::NACL_CACHE, cache_dir, cache_size, callback);
240 }
241
242 int PNaClTranslationCache::InitWithMemBackend(
243 int cache_size,
244 const net::CompletionCallback& callback) {
245 return Init(net::MEMORY_CACHE, base::FilePath(), cache_size, callback);
246 }
247
248 int PNaClTranslationCache::Init(net::CacheType cache_type,
249 const base::FilePath& cache_dir,
250 int cache_size,
251 const net::CompletionCallback& callback) {
252 int rv = disk_cache::CreateCacheBackend(
253 cache_type,
254 net::CACHE_BACKEND_DEFAULT,
255 cache_dir,
256 cache_size,
257 true /* force_initialize */,
258 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE),
259 NULL, /* dummy net log */
260 &disk_cache_,
261 base::Bind(&PNaClTranslationCache::OnCreateBackendComplete, AsWeakPtr()));
262 init_callback_ = callback;
263 if (rv != net::ERR_IO_PENDING) {
264 OnCreateBackendComplete(rv);
265 }
266 return rv;
267 }
268
269 void PNaClTranslationCache::OnCreateBackendComplete(int rv) {
270 // Invoke our client's callback function.
271 if (!init_callback_.is_null()) {
272 init_callback_.Run(rv);
273 init_callback_.Reset();
274 }
275 }
276
277 //////////////////////////////////////////////////////////////////////
278 // High-level API
279
280 // TODO(dschuff): Surely there must be a way to just create a null callback?
281 static void NullCallback(int ignored) {}
282
283 void PNaClTranslationCache::StoreNexe(const std::string& key,
284 const std::string& nexe) {
285 StoreNexe(key, nexe, base::Bind(NullCallback));
286 }
287
288 void PNaClTranslationCache::StoreNexe(const std::string& key,
289 const std::string& nexe,
290 const net::CompletionCallback& callback) {
291 PNaClTranslationCacheWriteEntry* entry =
292 new PNaClTranslationCacheWriteEntry(AsWeakPtr(), key, nexe, callback);
293 write_entries_[entry] = entry;
294 entry->Cache();
295 }
296
297 int PNaClTranslationCache::GetNexe(const std::string& key,
298 std::string* nexe,
299 const net::CompletionCallback& callback) {
300 // TODO(dschuff): Actually find the entry, and do the right thing.
301 // Shader cache ended up making a separate ReadHelper, analogous
302 // to the PNaClTranslationCacheWriteEntry.
303 return net::OK;
304 }
305
306 int PNaClTranslationCache::InitCache(const base::FilePath& cache_directory,
307 bool in_memory,
308 const net::CompletionCallback& callback) {
309 int rv;
310 in_memory_ = in_memory;
311 if (in_memory_) {
312 rv = InitWithMemBackend(kMaxMemCacheSize, callback);
313 } else {
314 rv = InitWithDiskBackend(cache_directory.Append(kDiskCacheDirectoryName),
315 kMaxDiskCacheSize,
316 callback);
317 }
318
319 return rv;
320 }
321
322 int PNaClTranslationCache::Size() {
323 if (!disk_cache_)
324 return -1;
325 return disk_cache_->GetEntryCount();
326 }
327
328 } // namespace nacl_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698