Index: content/browser/appcache/appcache_disk_cache.cc |
diff --git a/content/browser/appcache/appcache_disk_cache.cc b/content/browser/appcache/appcache_disk_cache.cc |
index 382ed45fed2197ae8be5b861e1f310d18a118694..46f406eb6997c6815c25cd69fe669cae45799950 100644 |
--- a/content/browser/appcache/appcache_disk_cache.cc |
+++ b/content/browser/appcache/appcache_disk_cache.cc |
@@ -8,6 +8,7 @@ |
#include "base/bind_helpers.h" |
#include "base/files/file_path.h" |
#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
#include "base/single_thread_task_runner.h" |
#include "base/stl_util.h" |
#include "base/strings/string_number_conversions.h" |
@@ -114,70 +115,91 @@ class AppCacheDiskCache::EntryImpl : public Entry { |
// Separate object to hold state for each Create, Delete, or Doom call |
// while the call is in-flight and to produce an EntryImpl upon completion. |
-class AppCacheDiskCache::ActiveCall { |
+class AppCacheDiskCache::ActiveCall |
+ : public base::RefCounted<AppCacheDiskCache::ActiveCall> { |
public: |
- explicit ActiveCall(AppCacheDiskCache* owner) |
- : entry_(NULL), |
- owner_(owner), |
- entry_ptr_(NULL) { |
+ static int CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner, |
+ int64 key, Entry** entry, |
+ const net::CompletionCallback& callback) { |
+ scoped_refptr<ActiveCall> active_call( |
+ new ActiveCall(owner, entry, callback)); |
+ int rv = owner->disk_cache()->CreateEntry( |
+ base::Int64ToString(key), &active_call->entry_ptr_, |
+ base::Bind(&ActiveCall::OnAsyncCompletion, active_call)); |
+ return active_call->HandleImmediateReturnValue(rv); |
} |
- int CreateEntry(int64 key, Entry** entry, |
- const net::CompletionCallback& callback) { |
- int rv = owner_->disk_cache()->CreateEntry( |
- base::Int64ToString(key), &entry_ptr_, |
- base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); |
- return HandleImmediateReturnValue(rv, entry, callback); |
+ static int OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner, |
+ int64 key, Entry** entry, |
+ const net::CompletionCallback& callback) { |
+ scoped_refptr<ActiveCall> active_call( |
+ new ActiveCall(owner, entry, callback)); |
+ int rv = owner->disk_cache()->OpenEntry( |
+ base::Int64ToString(key), &active_call->entry_ptr_, |
+ base::Bind(&ActiveCall::OnAsyncCompletion, active_call)); |
+ return active_call->HandleImmediateReturnValue(rv); |
} |
- int OpenEntry(int64 key, Entry** entry, |
- const net::CompletionCallback& callback) { |
- int rv = owner_->disk_cache()->OpenEntry( |
- base::Int64ToString(key), &entry_ptr_, |
- base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); |
- return HandleImmediateReturnValue(rv, entry, callback); |
- } |
- |
- int DoomEntry(int64 key, const net::CompletionCallback& callback) { |
- int rv = owner_->disk_cache()->DoomEntry( |
+ static int DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner, |
+ int64 key, const net::CompletionCallback& callback) { |
+ scoped_refptr<ActiveCall> active_call( |
+ new ActiveCall(owner, nullptr, callback)); |
+ int rv = owner->disk_cache()->DoomEntry( |
base::Int64ToString(key), |
- base::Bind(&ActiveCall::OnAsyncCompletion, base::Unretained(this))); |
- return HandleImmediateReturnValue(rv, NULL, callback); |
+ base::Bind(&ActiveCall::OnAsyncCompletion, active_call)); |
+ return active_call->HandleImmediateReturnValue(rv); |
} |
private: |
- int HandleImmediateReturnValue(int rv, Entry** entry, |
- const net::CompletionCallback& callback) { |
+ friend class base::RefCounted<AppCacheDiskCache::ActiveCall>; |
+ |
+ ActiveCall(const base::WeakPtr<AppCacheDiskCache>& owner, |
+ Entry** entry, |
+ const net::CompletionCallback& callback) |
+ : owner_(owner), |
+ entry_(entry), |
+ callback_(callback), |
+ entry_ptr_(nullptr) { |
+ DCHECK(owner_); |
+ } |
+ |
+ ~ActiveCall() {} |
+ |
+ int HandleImmediateReturnValue(int rv) { |
if (rv == net::ERR_IO_PENDING) { |
// OnAsyncCompletion will be called later. |
- callback_ = callback; |
- entry_ = entry; |
- owner_->AddActiveCall(this); |
- return net::ERR_IO_PENDING; |
+ return rv; |
+ } |
+ |
+ if (rv == net::OK && entry_) { |
+ DCHECK(entry_ptr_); |
+ *entry_ = new EntryImpl(entry_ptr_, owner_.get()); |
} |
- if (rv == net::OK && entry) |
- *entry = new EntryImpl(entry_ptr_, owner_); |
- delete this; |
return rv; |
} |
void OnAsyncCompletion(int rv) { |
- owner_->RemoveActiveCall(this); |
- if (rv == net::OK && entry_) |
- *entry_ = new EntryImpl(entry_ptr_, owner_); |
+ if (rv == net::OK && entry_) { |
+ DCHECK(entry_ptr_); |
+ if (owner_) { |
+ *entry_ = new EntryImpl(entry_ptr_, owner_.get()); |
+ } else { |
+ entry_ptr_->Close(); |
+ rv = net::ERR_ABORTED; |
+ } |
+ } |
callback_.Run(rv); |
- callback_.Reset(); |
- delete this; |
} |
+ base::WeakPtr<AppCacheDiskCache> owner_; |
Entry** entry_; |
net::CompletionCallback callback_; |
- AppCacheDiskCache* owner_; |
disk_cache::Entry* entry_ptr_; |
}; |
AppCacheDiskCache::AppCacheDiskCache() |
- : is_disabled_(false) { |
+ : is_disabled_(false), |
+ weak_factory_(this) { |
} |
AppCacheDiskCache::~AppCacheDiskCache() { |
@@ -225,7 +247,6 @@ void AppCacheDiskCache::Disable() { |
} |
open_entries_.clear(); |
disk_cache_.reset(); |
- STLDeleteElements(&active_calls_); |
} |
int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |
@@ -243,7 +264,8 @@ int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |
if (!disk_cache_) |
return net::ERR_FAILED; |
- return (new ActiveCall(this))->CreateEntry(key, entry, callback); |
+ return ActiveCall::CreateEntry( |
+ weak_factory_.GetWeakPtr(), key, entry, callback); |
} |
int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, |
@@ -261,7 +283,8 @@ int AppCacheDiskCache::OpenEntry(int64 key, Entry** entry, |
if (!disk_cache_) |
return net::ERR_FAILED; |
- return (new ActiveCall(this))->OpenEntry(key, entry, callback); |
+ return ActiveCall::OpenEntry( |
+ weak_factory_.GetWeakPtr(), key, entry, callback); |
} |
int AppCacheDiskCache::DoomEntry(int64 key, |
@@ -278,7 +301,7 @@ int AppCacheDiskCache::DoomEntry(int64 key, |
if (!disk_cache_) |
return net::ERR_FAILED; |
- return (new ActiveCall(this))->DoomEntry(key, callback); |
+ return ActiveCall::DoomEntry(weak_factory_.GetWeakPtr(), key, callback); |
} |
AppCacheDiskCache::PendingCall::PendingCall() |