OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |