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

Side by Side Diff: webkit/browser/appcache/appcache_disk_cache.cc

Issue 344493002: Move all remaining appcache-related code to content namespace (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 5 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) 2012 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 "webkit/browser/appcache/appcache_disk_cache.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "net/base/cache_type.h"
14 #include "net/base/net_errors.h"
15
16 namespace appcache {
17
18 // A callback shim that provides storage for the 'backend_ptr' value
19 // and will delete a resulting ptr if completion occurs after its
20 // been canceled.
21 class AppCacheDiskCache::CreateBackendCallbackShim
22 : public base::RefCounted<CreateBackendCallbackShim> {
23 public:
24 explicit CreateBackendCallbackShim(AppCacheDiskCache* object)
25 : appcache_diskcache_(object) {
26 }
27
28 void Cancel() {
29 appcache_diskcache_ = NULL;
30 }
31
32 void Callback(int rv) {
33 if (appcache_diskcache_)
34 appcache_diskcache_->OnCreateBackendComplete(rv);
35 }
36
37 scoped_ptr<disk_cache::Backend> backend_ptr_; // Accessed directly.
38
39 private:
40 friend class base::RefCounted<CreateBackendCallbackShim>;
41
42 ~CreateBackendCallbackShim() {
43 }
44
45 AppCacheDiskCache* appcache_diskcache_; // Unowned pointer.
46 };
47
48 // An implementation of AppCacheDiskCacheInterface::Entry that's a thin
49 // wrapper around disk_cache::Entry.
50 class AppCacheDiskCache::EntryImpl : public Entry {
51 public:
52 EntryImpl(disk_cache::Entry* disk_cache_entry,
53 AppCacheDiskCache* owner)
54 : disk_cache_entry_(disk_cache_entry), owner_(owner) {
55 DCHECK(disk_cache_entry);
56 DCHECK(owner);
57 owner_->AddOpenEntry(this);
58 }
59
60 // Entry implementation.
61 virtual int Read(int index, int64 offset, net::IOBuffer* buf, int buf_len,
62 const net::CompletionCallback& callback) OVERRIDE {
63 if (offset < 0 || offset > kint32max)
64 return net::ERR_INVALID_ARGUMENT;
65 if (!disk_cache_entry_)
66 return net::ERR_ABORTED;
67 return disk_cache_entry_->ReadData(
68 index, static_cast<int>(offset), buf, buf_len, callback);
69 }
70
71 virtual int Write(int index, int64 offset, net::IOBuffer* buf, int buf_len,
72 const net::CompletionCallback& callback) OVERRIDE {
73 if (offset < 0 || offset > kint32max)
74 return net::ERR_INVALID_ARGUMENT;
75 if (!disk_cache_entry_)
76 return net::ERR_ABORTED;
77 const bool kTruncate = true;
78 return disk_cache_entry_->WriteData(
79 index, static_cast<int>(offset), buf, buf_len, callback, kTruncate);
80 }
81
82 virtual int64 GetSize(int index) OVERRIDE {
83 return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L;
84 }
85
86 virtual void Close() OVERRIDE {
87 if (disk_cache_entry_)
88 disk_cache_entry_->Close();
89 delete this;
90 }
91
92 void Abandon() {
93 owner_ = NULL;
94 disk_cache_entry_->Close();
95 disk_cache_entry_ = NULL;
96 }
97
98 private:
99 virtual ~EntryImpl() {
100 if (owner_)
101 owner_->RemoveOpenEntry(this);
102 }
103
104 disk_cache::Entry* disk_cache_entry_;
105 AppCacheDiskCache* owner_;
106 };
107
108 // Separate object to hold state for each Create, Delete, or Doom call
109 // while the call is in-flight and to produce an EntryImpl upon completion.
110 class AppCacheDiskCache::ActiveCall {
111 public:
112 explicit ActiveCall(AppCacheDiskCache* owner)
113 : entry_(NULL),
114 owner_(owner),
115 entry_ptr_(NULL) {
116 }
117
118 int CreateEntry(int64 key, Entry** entry,
119 const net::CompletionCallback& callback) {
120 int rv = owner_->disk_cache()->CreateEntry(
121 base::Int64ToString(key), &entry_ptr_,
122 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this)));
123 return HandleImmediateReturnValue(rv, entry, callback);
124 }
125
126 int OpenEntry(int64 key, Entry** entry,
127 const net::CompletionCallback& callback) {
128 int rv = owner_->disk_cache()->OpenEntry(
129 base::Int64ToString(key), &entry_ptr_,
130 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this)));
131 return HandleImmediateReturnValue(rv, entry, callback);
132 }
133
134 int DoomEntry(int64 key, const net::CompletionCallback& callback) {
135 int rv = owner_->disk_cache()->DoomEntry(
136 base::Int64ToString(key),
137 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this)));
138 return HandleImmediateReturnValue(rv, NULL, callback);
139 }
140
141 private:
142 int HandleImmediateReturnValue(int rv, Entry** entry,
143 const net::CompletionCallback& callback) {
144 if (rv == net::ERR_IO_PENDING) {
145 // OnAsyncCompletion will be called later.
146 callback_ = callback;
147 entry_ = entry;
148 owner_->AddActiveCall(this);
149 return net::ERR_IO_PENDING;
150 }
151 if (rv == net::OK && entry)
152 *entry = new EntryImpl(entry_ptr_, owner_);
153 delete this;
154 return rv;
155 }
156
157 void OnAsyncCompletion(int rv) {
158 owner_->RemoveActiveCall(this);
159 if (rv == net::OK && entry_)
160 *entry_ = new EntryImpl(entry_ptr_, owner_);
161 callback_.Run(rv);
162 callback_.Reset();
163 delete this;
164 }
165
166 Entry** entry_;
167 net::CompletionCallback callback_;
168 AppCacheDiskCache* owner_;
169 disk_cache::Entry* entry_ptr_;
170 };
171
172 AppCacheDiskCache::AppCacheDiskCache()
173 : is_disabled_(false) {
174 }
175
176 AppCacheDiskCache::~AppCacheDiskCache() {
177 Disable();
178 }
179
180 int AppCacheDiskCache::InitWithDiskBackend(
181 const base::FilePath& disk_cache_directory, int disk_cache_size, bool force,
182 base::MessageLoopProxy* cache_thread,
183 const net::CompletionCallback& callback) {
184 return Init(net::APP_CACHE, disk_cache_directory,
185 disk_cache_size, force, cache_thread, callback);
186 }
187
188 int AppCacheDiskCache::InitWithMemBackend(
189 int mem_cache_size, const net::CompletionCallback& callback) {
190 return Init(net::MEMORY_CACHE, base::FilePath(), mem_cache_size, false, NULL,
191 callback);
192 }
193
194 void AppCacheDiskCache::Disable() {
195 if (is_disabled_)
196 return;
197
198 is_disabled_ = true;
199
200 if (create_backend_callback_.get()) {
201 create_backend_callback_->Cancel();
202 create_backend_callback_ = NULL;
203 OnCreateBackendComplete(net::ERR_ABORTED);
204 }
205
206 // We need to close open file handles in order to reinitalize the
207 // appcache system on the fly. File handles held in both entries and in
208 // the main disk_cache::Backend class need to be released.
209 for (OpenEntries::const_iterator iter = open_entries_.begin();
210 iter != open_entries_.end(); ++iter) {
211 (*iter)->Abandon();
212 }
213 open_entries_.clear();
214 disk_cache_.reset();
215 STLDeleteElements(&active_calls_);
216 }
217
218 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry,
219 const net::CompletionCallback& callback) {
220 DCHECK(entry);
221 DCHECK(!callback.is_null());
222 if (is_disabled_)
223 return net::ERR_ABORTED;
224
225 if (is_initializing()) {
226 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback));
227 return net::ERR_IO_PENDING;
228 }
229
230 if (!disk_cache_)
231 return net::ERR_FAILED;
232
233 return (new ActiveCall(this))->CreateEntry(key, entry, callback);
234 }
235
236 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry,
237 const net::CompletionCallback& callback) {
238 DCHECK(entry);
239 DCHECK(!callback.is_null());
240 if (is_disabled_)
241 return net::ERR_ABORTED;
242
243 if (is_initializing()) {
244 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback));
245 return net::ERR_IO_PENDING;
246 }
247
248 if (!disk_cache_)
249 return net::ERR_FAILED;
250
251 return (new ActiveCall(this))->OpenEntry(key, entry, callback);
252 }
253
254 int AppCacheDiskCache::DoomEntry(int64 key,
255 const net::CompletionCallback& callback) {
256 DCHECK(!callback.is_null());
257 if (is_disabled_)
258 return net::ERR_ABORTED;
259
260 if (is_initializing()) {
261 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback));
262 return net::ERR_IO_PENDING;
263 }
264
265 if (!disk_cache_)
266 return net::ERR_FAILED;
267
268 return (new ActiveCall(this))->DoomEntry(key, callback);
269 }
270
271 AppCacheDiskCache::PendingCall::PendingCall()
272 : call_type(CREATE),
273 key(0),
274 entry(NULL) {
275 }
276
277 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type,
278 int64 key,
279 Entry** entry,
280 const net::CompletionCallback& callback)
281 : call_type(call_type),
282 key(key),
283 entry(entry),
284 callback(callback) {
285 }
286
287 AppCacheDiskCache::PendingCall::~PendingCall() {}
288
289 int AppCacheDiskCache::Init(net::CacheType cache_type,
290 const base::FilePath& cache_directory,
291 int cache_size, bool force,
292 base::MessageLoopProxy* cache_thread,
293 const net::CompletionCallback& callback) {
294 DCHECK(!is_initializing() && !disk_cache_.get());
295 is_disabled_ = false;
296 create_backend_callback_ = new CreateBackendCallbackShim(this);
297
298 #if defined(APPCACHE_USE_SIMPLE_CACHE)
299 const net::BackendType backend_type = net::CACHE_BACKEND_SIMPLE;
300 #else
301 const net::BackendType backend_type = net::CACHE_BACKEND_DEFAULT;
302 #endif
303 int rv = disk_cache::CreateCacheBackend(
304 cache_type, backend_type, cache_directory, cache_size,
305 force, cache_thread, NULL, &(create_backend_callback_->backend_ptr_),
306 base::Bind(&CreateBackendCallbackShim::Callback,
307 create_backend_callback_));
308 if (rv == net::ERR_IO_PENDING)
309 init_callback_ = callback;
310 else
311 OnCreateBackendComplete(rv);
312 return rv;
313 }
314
315 void AppCacheDiskCache::OnCreateBackendComplete(int rv) {
316 if (rv == net::OK) {
317 disk_cache_ = create_backend_callback_->backend_ptr_.Pass();
318 }
319 create_backend_callback_ = NULL;
320
321 // Invoke our clients callback function.
322 if (!init_callback_.is_null()) {
323 init_callback_.Run(rv);
324 init_callback_.Reset();
325 }
326
327 // Service pending calls that were queued up while we were initializing.
328 for (PendingCalls::const_iterator iter = pending_calls_.begin();
329 iter < pending_calls_.end(); ++iter) {
330 int rv = net::ERR_FAILED;
331 switch (iter->call_type) {
332 case CREATE:
333 rv = CreateEntry(iter->key, iter->entry, iter->callback);
334 break;
335 case OPEN:
336 rv = OpenEntry(iter->key, iter->entry, iter->callback);
337 break;
338 case DOOM:
339 rv = DoomEntry(iter->key, iter->callback);
340 break;
341 default:
342 NOTREACHED();
343 break;
344 }
345 if (rv != net::ERR_IO_PENDING)
346 iter->callback.Run(rv);
347 }
348 pending_calls_.clear();
349 }
350
351 } // namespace appcache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698