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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/appcache/appcache_disk_cache.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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()
« 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