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

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

Issue 1136373003: AppCache: Ensure inflight ActiveCalls are not destroyed (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix win build failures Created 5 years, 7 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
« no previous file with comments | « content/browser/appcache/appcache_disk_cache.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "content/browser/appcache/appcache_disk_cache.h" 5 #include "content/browser/appcache/appcache_disk_cache.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/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
11 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
14 #include "net/base/cache_type.h" 15 #include "net/base/cache_type.h"
15 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
16 17
17 namespace content { 18 namespace content {
18 19
19 // A callback shim that provides storage for the 'backend_ptr' value 20 // A callback shim that provides storage for the 'backend_ptr' value
20 // and will delete a resulting ptr if completion occurs after its 21 // and will delete a resulting ptr if completion occurs after its
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 if (owner_) 108 if (owner_)
108 owner_->RemoveOpenEntry(this); 109 owner_->RemoveOpenEntry(this);
109 } 110 }
110 111
111 disk_cache::Entry* disk_cache_entry_; 112 disk_cache::Entry* disk_cache_entry_;
112 AppCacheDiskCache* owner_; 113 AppCacheDiskCache* owner_;
113 }; 114 };
114 115
115 // Separate object to hold state for each Create, Delete, or Doom call 116 // Separate object to hold state for each Create, Delete, or Doom call
116 // while the call is in-flight and to produce an EntryImpl upon completion. 117 // while the call is in-flight and to produce an EntryImpl upon completion.
117 class AppCacheDiskCache::ActiveCall { 118 class AppCacheDiskCache::ActiveCall
119 : public base::RefCounted<AppCacheDiskCache::ActiveCall> {
118 public: 120 public:
119 explicit ActiveCall(AppCacheDiskCache* owner) 121 static int CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
120 : entry_(NULL), 122 int64 key, Entry** entry,
121 owner_(owner), 123 const net::CompletionCallback& callback) {
122 entry_ptr_(NULL) { 124 scoped_refptr<ActiveCall> active_call(
125 new ActiveCall(owner, entry, callback));
126 int rv = owner->disk_cache()->CreateEntry(
127 base::Int64ToString(key), &active_call->entry_ptr_,
128 base::Bind(&ActiveCall::OnAsyncCompletion, active_call));
129 return active_call->HandleImmediateReturnValue(rv);
123 } 130 }
124 131
125 int CreateEntry(int64 key, Entry** entry, 132 static int OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
126 const net::CompletionCallback& callback) { 133 int64 key, Entry** entry,
127 int rv = owner_->disk_cache()->CreateEntry( 134 const net::CompletionCallback& callback) {
128 base::Int64ToString(key), &entry_ptr_, 135 scoped_refptr<ActiveCall> active_call(
129 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); 136 new ActiveCall(owner, entry, callback));
130 return HandleImmediateReturnValue(rv, entry, callback); 137 int rv = owner->disk_cache()->OpenEntry(
138 base::Int64ToString(key), &active_call->entry_ptr_,
139 base::Bind(&ActiveCall::OnAsyncCompletion, active_call));
140 return active_call->HandleImmediateReturnValue(rv);
131 } 141 }
132 142
133 int OpenEntry(int64 key, Entry** entry, 143 static int DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
134 const net::CompletionCallback& callback) { 144 int64 key, const net::CompletionCallback& callback) {
135 int rv = owner_->disk_cache()->OpenEntry( 145 scoped_refptr<ActiveCall> active_call(
136 base::Int64ToString(key), &entry_ptr_, 146 new ActiveCall(owner, nullptr, callback));
137 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); 147 int rv = owner->disk_cache()->DoomEntry(
138 return HandleImmediateReturnValue(rv, entry, callback);
139 }
140
141 int DoomEntry(int64 key, const net::CompletionCallback& callback) {
142 int rv = owner_->disk_cache()->DoomEntry(
143 base::Int64ToString(key), 148 base::Int64ToString(key),
144 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); 149 base::Bind(&ActiveCall::OnAsyncCompletion, active_call));
145 return HandleImmediateReturnValue(rv, NULL, callback); 150 return active_call->HandleImmediateReturnValue(rv);
146 } 151 }
147 152
148 private: 153 private:
149 int HandleImmediateReturnValue(int rv, Entry** entry, 154 friend class base::RefCounted<AppCacheDiskCache::ActiveCall>;
150 const net::CompletionCallback& callback) { 155
156 ActiveCall(const base::WeakPtr<AppCacheDiskCache>& owner,
157 Entry** entry,
158 const net::CompletionCallback& callback)
159 : owner_(owner),
160 entry_(entry),
161 callback_(callback),
162 entry_ptr_(nullptr) {
163 DCHECK(owner_);
164 }
165
166 ~ActiveCall() {}
167
168 int HandleImmediateReturnValue(int rv) {
151 if (rv == net::ERR_IO_PENDING) { 169 if (rv == net::ERR_IO_PENDING) {
152 // OnAsyncCompletion will be called later. 170 // OnAsyncCompletion will be called later.
153 callback_ = callback; 171 return rv;
154 entry_ = entry;
155 owner_->AddActiveCall(this);
156 return net::ERR_IO_PENDING;
157 } 172 }
158 if (rv == net::OK && entry) 173
159 *entry = new EntryImpl(entry_ptr_, owner_); 174 if (rv == net::OK && entry_) {
160 delete this; 175 DCHECK(entry_ptr_);
176 *entry_ = new EntryImpl(entry_ptr_, owner_.get());
177 }
161 return rv; 178 return rv;
162 } 179 }
163 180
164 void OnAsyncCompletion(int rv) { 181 void OnAsyncCompletion(int rv) {
165 owner_->RemoveActiveCall(this); 182 if (rv == net::OK && entry_) {
166 if (rv == net::OK && entry_) 183 DCHECK(entry_ptr_);
167 *entry_ = new EntryImpl(entry_ptr_, owner_); 184 if (owner_) {
185 *entry_ = new EntryImpl(entry_ptr_, owner_.get());
186 } else {
187 entry_ptr_->Close();
188 rv = net::ERR_ABORTED;
189 }
190 }
168 callback_.Run(rv); 191 callback_.Run(rv);
169 callback_.Reset();
170 delete this;
171 } 192 }
172 193
194 base::WeakPtr<AppCacheDiskCache> owner_;
173 Entry** entry_; 195 Entry** entry_;
174 net::CompletionCallback callback_; 196 net::CompletionCallback callback_;
175 AppCacheDiskCache* owner_;
176 disk_cache::Entry* entry_ptr_; 197 disk_cache::Entry* entry_ptr_;
177 }; 198 };
178 199
179 AppCacheDiskCache::AppCacheDiskCache() 200 AppCacheDiskCache::AppCacheDiskCache()
180 : is_disabled_(false) { 201 : is_disabled_(false),
202 weak_factory_(this) {
181 } 203 }
182 204
183 AppCacheDiskCache::~AppCacheDiskCache() { 205 AppCacheDiskCache::~AppCacheDiskCache() {
184 Disable(); 206 Disable();
185 } 207 }
186 208
187 int AppCacheDiskCache::InitWithDiskBackend( 209 int AppCacheDiskCache::InitWithDiskBackend(
188 const base::FilePath& disk_cache_directory, 210 const base::FilePath& disk_cache_directory,
189 int disk_cache_size, 211 int disk_cache_size,
190 bool force, 212 bool force,
(...skipping 27 matching lines...) Expand all
218 240
219 // We need to close open file handles in order to reinitalize the 241 // We need to close open file handles in order to reinitalize the
220 // appcache system on the fly. File handles held in both entries and in 242 // appcache system on the fly. File handles held in both entries and in
221 // the main disk_cache::Backend class need to be released. 243 // the main disk_cache::Backend class need to be released.
222 for (OpenEntries::const_iterator iter = open_entries_.begin(); 244 for (OpenEntries::const_iterator iter = open_entries_.begin();
223 iter != open_entries_.end(); ++iter) { 245 iter != open_entries_.end(); ++iter) {
224 (*iter)->Abandon(); 246 (*iter)->Abandon();
225 } 247 }
226 open_entries_.clear(); 248 open_entries_.clear();
227 disk_cache_.reset(); 249 disk_cache_.reset();
228 STLDeleteElements(&active_calls_);
229 } 250 }
230 251
231 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, 252 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry,
232 const net::CompletionCallback& callback) { 253 const net::CompletionCallback& callback) {
233 DCHECK(entry); 254 DCHECK(entry);
234 DCHECK(!callback.is_null()); 255 DCHECK(!callback.is_null());
235 if (is_disabled_) 256 if (is_disabled_)
236 return net::ERR_ABORTED; 257 return net::ERR_ABORTED;
237 258
238 if (is_initializing()) { 259 if (is_initializing()) {
239 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback)); 260 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback));
240 return net::ERR_IO_PENDING; 261 return net::ERR_IO_PENDING;
241 } 262 }
242 263
243 if (!disk_cache_) 264 if (!disk_cache_)
244 return net::ERR_FAILED; 265 return net::ERR_FAILED;
245 266
246 return (new ActiveCall(this))->CreateEntry(key, entry, callback); 267 return ActiveCall::CreateEntry(
268 weak_factory_.GetWeakPtr(), key, entry, callback);
247 } 269 }
248 270
249 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, 271 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry,
250 const net::CompletionCallback& callback) { 272 const net::CompletionCallback& callback) {
251 DCHECK(entry); 273 DCHECK(entry);
252 DCHECK(!callback.is_null()); 274 DCHECK(!callback.is_null());
253 if (is_disabled_) 275 if (is_disabled_)
254 return net::ERR_ABORTED; 276 return net::ERR_ABORTED;
255 277
256 if (is_initializing()) { 278 if (is_initializing()) {
257 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback)); 279 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback));
258 return net::ERR_IO_PENDING; 280 return net::ERR_IO_PENDING;
259 } 281 }
260 282
261 if (!disk_cache_) 283 if (!disk_cache_)
262 return net::ERR_FAILED; 284 return net::ERR_FAILED;
263 285
264 return (new ActiveCall(this))->OpenEntry(key, entry, callback); 286 return ActiveCall::OpenEntry(
287 weak_factory_.GetWeakPtr(), key, entry, callback);
265 } 288 }
266 289
267 int AppCacheDiskCache::DoomEntry(int64 key, 290 int AppCacheDiskCache::DoomEntry(int64 key,
268 const net::CompletionCallback& callback) { 291 const net::CompletionCallback& callback) {
269 DCHECK(!callback.is_null()); 292 DCHECK(!callback.is_null());
270 if (is_disabled_) 293 if (is_disabled_)
271 return net::ERR_ABORTED; 294 return net::ERR_ABORTED;
272 295
273 if (is_initializing()) { 296 if (is_initializing()) {
274 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback)); 297 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback));
275 return net::ERR_IO_PENDING; 298 return net::ERR_IO_PENDING;
276 } 299 }
277 300
278 if (!disk_cache_) 301 if (!disk_cache_)
279 return net::ERR_FAILED; 302 return net::ERR_FAILED;
280 303
281 return (new ActiveCall(this))->DoomEntry(key, callback); 304 return ActiveCall::DoomEntry(weak_factory_.GetWeakPtr(), key, callback);
282 } 305 }
283 306
284 AppCacheDiskCache::PendingCall::PendingCall() 307 AppCacheDiskCache::PendingCall::PendingCall()
285 : call_type(CREATE), 308 : call_type(CREATE),
286 key(0), 309 key(0),
287 entry(NULL) { 310 entry(NULL) {
288 } 311 }
289 312
290 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type, 313 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type,
291 int64 key, 314 int64 key,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 NOTREACHED(); 386 NOTREACHED();
364 break; 387 break;
365 } 388 }
366 if (rv != net::ERR_IO_PENDING) 389 if (rv != net::ERR_IO_PENDING)
367 iter->callback.Run(rv); 390 iter->callback.Run(rv);
368 } 391 }
369 pending_calls_.clear(); 392 pending_calls_.clear();
370 } 393 }
371 394
372 } // namespace content 395 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/appcache/appcache_disk_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698