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..7bb77d54daba048c4febaff225a44598cae8a994 100644 |
--- a/content/browser/appcache/appcache_disk_cache.cc |
+++ b/content/browser/appcache/appcache_disk_cache.cc |
@@ -116,68 +116,86 @@ class AppCacheDiskCache::EntryImpl : public Entry { |
// while the call is in-flight and to produce an EntryImpl upon completion. |
class 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) { |
+ 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, |
+ 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
|
+ 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) { |
+ 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, |
+ base::Unretained(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) { |
+ 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, |
+ base::Unretained(active_call))); |
+ return active_call->HandleImmediateReturnValue(rv); |
} |
private: |
- int HandleImmediateReturnValue(int rv, Entry** entry, |
- const net::CompletionCallback& callback) { |
+ ActiveCall(const base::WeakPtr<AppCacheDiskCache>& owner, |
+ Entry** entry, |
+ const net::CompletionCallback& callback) |
+ : owner_(owner), |
+ entry_(entry), |
+ callback_(callback), |
+ entry_ptr_(nullptr) { |
+ DCHECK(owner_); |
+ } |
+ |
+ 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 +243,6 @@ void AppCacheDiskCache::Disable() { |
} |
open_entries_.clear(); |
disk_cache_.reset(); |
- STLDeleteElements(&active_calls_); |
} |
int AppCacheDiskCache::CreateEntry(int64 key, Entry** entry, |
@@ -243,7 +260,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 +279,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 +297,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() |