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

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 test 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"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 110
111 disk_cache::Entry* disk_cache_entry_; 111 disk_cache::Entry* disk_cache_entry_;
112 AppCacheDiskCache* owner_; 112 AppCacheDiskCache* owner_;
113 }; 113 };
114 114
115 // Separate object to hold state for each Create, Delete, or Doom call 115 // 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. 116 // while the call is in-flight and to produce an EntryImpl upon completion.
117 class AppCacheDiskCache::ActiveCall { 117 class AppCacheDiskCache::ActiveCall {
118 public: 118 public:
119 explicit ActiveCall(AppCacheDiskCache* owner) 119 static int CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
120 : entry_(NULL), 120 int64 key, Entry** entry,
121 owner_(owner), 121 const net::CompletionCallback& callback) {
122 entry_ptr_(NULL) { 122 ActiveCall* active_call = new ActiveCall(owner, entry, callback);
123 int rv = owner->disk_cache()->CreateEntry(
124 base::Int64ToString(key), &active_call->entry_ptr_,
125 base::Bind(&ActiveCall::OnAsyncCompletion,
126 base::Unretained(active_call)));
michaeln 2015/05/14 23:24:00 Hmmm... I think this will leak ActiveCall instance
nhiroki 2015/05/15 00:42:08 Oh...
nhiroki 2015/05/15 01:02:25 Uploaded a refcounted version to PS4
127 return active_call->HandleImmediateReturnValue(rv);
123 } 128 }
124 129
125 int CreateEntry(int64 key, Entry** entry, 130 static int OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
126 const net::CompletionCallback& callback) { 131 int64 key, Entry** entry,
127 int rv = owner_->disk_cache()->CreateEntry( 132 const net::CompletionCallback& callback) {
128 base::Int64ToString(key), &entry_ptr_, 133 ActiveCall* active_call = new ActiveCall(owner, entry, callback);
129 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); 134 int rv = owner->disk_cache()->OpenEntry(
130 return HandleImmediateReturnValue(rv, entry, callback); 135 base::Int64ToString(key), &active_call->entry_ptr_,
136 base::Bind(&ActiveCall::OnAsyncCompletion,
137 base::Unretained(active_call)));
138 return active_call->HandleImmediateReturnValue(rv);
131 } 139 }
132 140
133 int OpenEntry(int64 key, Entry** entry, 141 static int DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
134 const net::CompletionCallback& callback) { 142 int64 key, const net::CompletionCallback& callback) {
135 int rv = owner_->disk_cache()->OpenEntry( 143 ActiveCall* active_call = new ActiveCall(owner, nullptr, callback);
136 base::Int64ToString(key), &entry_ptr_, 144 int rv = owner->disk_cache()->DoomEntry(
137 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this)));
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), 145 base::Int64ToString(key),
144 base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); 146 base::Bind(&ActiveCall::OnAsyncCompletion,
145 return HandleImmediateReturnValue(rv, NULL, callback); 147 base::Unretained(active_call)));
148 return active_call->HandleImmediateReturnValue(rv);
146 } 149 }
147 150
148 private: 151 private:
149 int HandleImmediateReturnValue(int rv, Entry** entry, 152 ActiveCall(const base::WeakPtr<AppCacheDiskCache>& owner,
150 const net::CompletionCallback& callback) { 153 Entry** entry,
154 const net::CompletionCallback& callback)
155 : owner_(owner),
156 entry_(entry),
157 callback_(callback),
158 entry_ptr_(nullptr) {
159 DCHECK(owner_);
160 }
161
162 int HandleImmediateReturnValue(int rv) {
151 if (rv == net::ERR_IO_PENDING) { 163 if (rv == net::ERR_IO_PENDING) {
152 // OnAsyncCompletion will be called later. 164 // OnAsyncCompletion will be called later.
153 callback_ = callback; 165 return rv;
154 entry_ = entry;
155 owner_->AddActiveCall(this);
156 return net::ERR_IO_PENDING;
157 } 166 }
158 if (rv == net::OK && entry) 167
159 *entry = new EntryImpl(entry_ptr_, owner_); 168 if (rv == net::OK && entry_) {
169 DCHECK(entry_ptr_);
170 *entry_ = new EntryImpl(entry_ptr_, owner_.get());
171 }
160 delete this; 172 delete this;
161 return rv; 173 return rv;
162 } 174 }
163 175
164 void OnAsyncCompletion(int rv) { 176 void OnAsyncCompletion(int rv) {
165 owner_->RemoveActiveCall(this); 177 if (rv == net::OK && entry_) {
166 if (rv == net::OK && entry_) 178 DCHECK(entry_ptr_);
167 *entry_ = new EntryImpl(entry_ptr_, owner_); 179 if (owner_) {
180 *entry_ = new EntryImpl(entry_ptr_, owner_.get());
181 } else {
182 entry_ptr_->Close();
183 rv = net::ERR_ABORTED;
184 }
185 }
168 callback_.Run(rv); 186 callback_.Run(rv);
169 callback_.Reset();
170 delete this; 187 delete this;
171 } 188 }
172 189
190 base::WeakPtr<AppCacheDiskCache> owner_;
173 Entry** entry_; 191 Entry** entry_;
174 net::CompletionCallback callback_; 192 net::CompletionCallback callback_;
175 AppCacheDiskCache* owner_;
176 disk_cache::Entry* entry_ptr_; 193 disk_cache::Entry* entry_ptr_;
177 }; 194 };
178 195
179 AppCacheDiskCache::AppCacheDiskCache() 196 AppCacheDiskCache::AppCacheDiskCache()
180 : is_disabled_(false) { 197 : is_disabled_(false),
198 weak_factory_(this) {
181 } 199 }
182 200
183 AppCacheDiskCache::~AppCacheDiskCache() { 201 AppCacheDiskCache::~AppCacheDiskCache() {
184 Disable(); 202 Disable();
185 } 203 }
186 204
187 int AppCacheDiskCache::InitWithDiskBackend( 205 int AppCacheDiskCache::InitWithDiskBackend(
188 const base::FilePath& disk_cache_directory, 206 const base::FilePath& disk_cache_directory,
189 int disk_cache_size, 207 int disk_cache_size,
190 bool force, 208 bool force,
(...skipping 27 matching lines...) Expand all
218 236
219 // We need to close open file handles in order to reinitalize the 237 // 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 238 // appcache system on the fly. File handles held in both entries and in
221 // the main disk_cache::Backend class need to be released. 239 // the main disk_cache::Backend class need to be released.
222 for (OpenEntries::const_iterator iter = open_entries_.begin(); 240 for (OpenEntries::const_iterator iter = open_entries_.begin();
223 iter != open_entries_.end(); ++iter) { 241 iter != open_entries_.end(); ++iter) {
224 (*iter)->Abandon(); 242 (*iter)->Abandon();
225 } 243 }
226 open_entries_.clear(); 244 open_entries_.clear();
227 disk_cache_.reset(); 245 disk_cache_.reset();
228 STLDeleteElements(&active_calls_);
229 } 246 }
230 247
231 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, 248 int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry,
232 const net::CompletionCallback& callback) { 249 const net::CompletionCallback& callback) {
233 DCHECK(entry); 250 DCHECK(entry);
234 DCHECK(!callback.is_null()); 251 DCHECK(!callback.is_null());
235 if (is_disabled_) 252 if (is_disabled_)
236 return net::ERR_ABORTED; 253 return net::ERR_ABORTED;
237 254
238 if (is_initializing()) { 255 if (is_initializing()) {
239 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback)); 256 pending_calls_.push_back(PendingCall(CREATE, key, entry, callback));
240 return net::ERR_IO_PENDING; 257 return net::ERR_IO_PENDING;
241 } 258 }
242 259
243 if (!disk_cache_) 260 if (!disk_cache_)
244 return net::ERR_FAILED; 261 return net::ERR_FAILED;
245 262
246 return (new ActiveCall(this))->CreateEntry(key, entry, callback); 263 return ActiveCall::CreateEntry(
264 weak_factory_.GetWeakPtr(), key, entry, callback);
247 } 265 }
248 266
249 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, 267 int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry,
250 const net::CompletionCallback& callback) { 268 const net::CompletionCallback& callback) {
251 DCHECK(entry); 269 DCHECK(entry);
252 DCHECK(!callback.is_null()); 270 DCHECK(!callback.is_null());
253 if (is_disabled_) 271 if (is_disabled_)
254 return net::ERR_ABORTED; 272 return net::ERR_ABORTED;
255 273
256 if (is_initializing()) { 274 if (is_initializing()) {
257 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback)); 275 pending_calls_.push_back(PendingCall(OPEN, key, entry, callback));
258 return net::ERR_IO_PENDING; 276 return net::ERR_IO_PENDING;
259 } 277 }
260 278
261 if (!disk_cache_) 279 if (!disk_cache_)
262 return net::ERR_FAILED; 280 return net::ERR_FAILED;
263 281
264 return (new ActiveCall(this))->OpenEntry(key, entry, callback); 282 return ActiveCall::OpenEntry(
283 weak_factory_.GetWeakPtr(), key, entry, callback);
265 } 284 }
266 285
267 int AppCacheDiskCache::DoomEntry(int64 key, 286 int AppCacheDiskCache::DoomEntry(int64 key,
268 const net::CompletionCallback& callback) { 287 const net::CompletionCallback& callback) {
269 DCHECK(!callback.is_null()); 288 DCHECK(!callback.is_null());
270 if (is_disabled_) 289 if (is_disabled_)
271 return net::ERR_ABORTED; 290 return net::ERR_ABORTED;
272 291
273 if (is_initializing()) { 292 if (is_initializing()) {
274 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback)); 293 pending_calls_.push_back(PendingCall(DOOM, key, NULL, callback));
275 return net::ERR_IO_PENDING; 294 return net::ERR_IO_PENDING;
276 } 295 }
277 296
278 if (!disk_cache_) 297 if (!disk_cache_)
279 return net::ERR_FAILED; 298 return net::ERR_FAILED;
280 299
281 return (new ActiveCall(this))->DoomEntry(key, callback); 300 return ActiveCall::DoomEntry(weak_factory_.GetWeakPtr(), key, callback);
282 } 301 }
283 302
284 AppCacheDiskCache::PendingCall::PendingCall() 303 AppCacheDiskCache::PendingCall::PendingCall()
285 : call_type(CREATE), 304 : call_type(CREATE),
286 key(0), 305 key(0),
287 entry(NULL) { 306 entry(NULL) {
288 } 307 }
289 308
290 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type, 309 AppCacheDiskCache::PendingCall::PendingCall(PendingCallType call_type,
291 int64 key, 310 int64 key,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 NOTREACHED(); 382 NOTREACHED();
364 break; 383 break;
365 } 384 }
366 if (rv != net::ERR_IO_PENDING) 385 if (rv != net::ERR_IO_PENDING)
367 iter->callback.Run(rv); 386 iter->callback.Run(rv);
368 } 387 }
369 pending_calls_.clear(); 388 pending_calls_.clear();
370 } 389 }
371 390
372 } // namespace content 391 } // 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