Index: net/disk_cache/simple/simple_entry_impl.cc |
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc |
index 1917a88715091ac1a37be9dae3b8fd104b6f4edf..63d16614827d7e52b926c926d744f7f3c149f4c1 100644 |
--- a/net/disk_cache/simple/simple_entry_impl.cc |
+++ b/net/disk_cache/simple/simple_entry_impl.cc |
@@ -30,11 +30,10 @@ namespace disk_cache { |
using base::FilePath; |
using base::MessageLoopProxy; |
using base::Time; |
-using base::WeakPtr; |
using base::WorkerPool; |
// static |
-int SimpleEntryImpl::OpenEntry(WeakPtr<SimpleIndex> index, |
+int SimpleEntryImpl::OpenEntry(scoped_refptr<SimpleIndex> index, |
const FilePath& path, |
const std::string& key, |
Entry** entry, |
@@ -42,9 +41,11 @@ int SimpleEntryImpl::OpenEntry(WeakPtr<SimpleIndex> index, |
// TODO(gavinp): More closely unify the last_used_ in the |
// SimpleSynchronousEntry and the SimpleIndex. |
if (!index || index->UseIfExists(key)) { |
+ scoped_refptr<SimpleEntryImpl> new_entry = |
+ new SimpleEntryImpl(index, path, key); |
SynchronousCreationCallback sync_creation_callback = |
base::Bind(&SimpleEntryImpl::CreationOperationComplete, |
- index, callback, key, entry); |
+ new_entry, entry, callback); |
WorkerPool::PostTask(FROM_HERE, |
base::Bind(&SimpleSynchronousEntry::OpenEntry, path, |
key, MessageLoopProxy::current(), |
@@ -56,14 +57,16 @@ int SimpleEntryImpl::OpenEntry(WeakPtr<SimpleIndex> index, |
} |
// static |
-int SimpleEntryImpl::CreateEntry(WeakPtr<SimpleIndex> index, |
+int SimpleEntryImpl::CreateEntry(scoped_refptr<SimpleIndex> index, |
const FilePath& path, |
const std::string& key, |
Entry** entry, |
const CompletionCallback& callback) { |
+ scoped_refptr<SimpleEntryImpl> new_entry = |
+ new SimpleEntryImpl(index, path, key); |
SynchronousCreationCallback sync_creation_callback = |
base::Bind(&SimpleEntryImpl::CreationOperationComplete, |
- index, callback, key, entry); |
+ new_entry, entry, callback); |
WorkerPool::PostTask(FROM_HERE, |
base::Bind(&SimpleSynchronousEntry::CreateEntry, path, |
key, MessageLoopProxy::current(), |
@@ -73,7 +76,7 @@ int SimpleEntryImpl::CreateEntry(WeakPtr<SimpleIndex> index, |
} |
// static |
-int SimpleEntryImpl::DoomEntry(WeakPtr<SimpleIndex> index, |
+int SimpleEntryImpl::DoomEntry(scoped_refptr<SimpleIndex> index, |
const FilePath& path, |
const std::string& key, |
const CompletionCallback& callback) { |
@@ -88,6 +91,7 @@ int SimpleEntryImpl::DoomEntry(WeakPtr<SimpleIndex> index, |
void SimpleEntryImpl::Doom() { |
DCHECK(io_thread_checker_.CalledOnValidThread()); |
+ DCHECK(synchronous_entry_); |
#if defined(OS_POSIX) |
// This call to static SimpleEntryImpl::DoomEntry() will just erase the |
// underlying files. On POSIX, this is fine; the files are still open on the |
@@ -101,15 +105,14 @@ void SimpleEntryImpl::Doom() { |
void SimpleEntryImpl::Close() { |
DCHECK(io_thread_checker_.CalledOnValidThread()); |
- if (!synchronous_entry_in_use_by_worker_) { |
- WorkerPool::PostTask(FROM_HERE, |
- base::Bind(&SimpleSynchronousEntry::Close, |
- base::Unretained(synchronous_entry_)), |
- true); |
- } |
- // Entry::Close() is expected to release this entry. See disk_cache.h for |
- // details. |
- delete this; |
+ bool in_use = synchronous_entry_in_use_by_worker_; |
+ DCHECK((in_use && !HasOneRef()) || (!in_use && HasOneRef())); |
+ Release(); // Balanced in CreationOperationCompleted(). |
+ // At most one worker can be operating on our |synchronous_entry_| at a time, |
+ // and so if we were in use when we cleared |self_|, we should expect a single |
+ // reference from that operation now. |
+ if (in_use) |
+ DCHECK(HasOneRef()); |
} |
std::string SimpleEntryImpl::GetKey() const { |
@@ -151,8 +154,7 @@ int SimpleEntryImpl::ReadData(int index, |
index_->UseIfExists(key_); |
SynchronousOperationCallback sync_operation_callback = |
base::Bind(&SimpleEntryImpl::EntryOperationComplete, |
- index_, callback, weak_ptr_factory_.GetWeakPtr(), |
- synchronous_entry_); |
+ this, callback); |
WorkerPool::PostTask(FROM_HERE, |
base::Bind(&SimpleSynchronousEntry::ReadData, |
base::Unretained(synchronous_entry_), |
@@ -178,8 +180,7 @@ int SimpleEntryImpl::WriteData(int index, |
index_->UseIfExists(key_); |
SynchronousOperationCallback sync_operation_callback = |
base::Bind(&SimpleEntryImpl::EntryOperationComplete, |
- index_, callback, weak_ptr_factory_.GetWeakPtr(), |
- synchronous_entry_); |
+ this, callback); |
WorkerPool::PostTask(FROM_HERE, |
base::Bind(&SimpleSynchronousEntry::WriteData, |
base::Unretained(synchronous_entry_), |
@@ -238,70 +239,66 @@ int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { |
return net::ERR_FAILED; |
} |
-SimpleEntryImpl::SimpleEntryImpl( |
- SimpleSynchronousEntry* synchronous_entry, |
- WeakPtr<SimpleIndex> index) |
- : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
- path_(synchronous_entry->path()), |
- key_(synchronous_entry->key()), |
- synchronous_entry_(synchronous_entry), |
- synchronous_entry_in_use_by_worker_(false), |
- index_(index) { |
- DCHECK(synchronous_entry); |
- SetSynchronousData(); |
+SimpleEntryImpl::SimpleEntryImpl(scoped_refptr<SimpleIndex> index, |
+ const base::FilePath& path, |
+ const std::string& key) |
+ : index_(index), |
+ path_(path), |
+ key_(key), |
+ synchronous_entry_(NULL), |
+ synchronous_entry_in_use_by_worker_(false) { |
} |
SimpleEntryImpl::~SimpleEntryImpl() { |
DCHECK(io_thread_checker_.CalledOnValidThread()); |
+ if (synchronous_entry_) { |
+ WorkerPool::PostTask(FROM_HERE, |
+ base::Bind(&SimpleSynchronousEntry::Close, |
+ base::Unretained(synchronous_entry_)), |
+ true); |
+ } |
} |
-// static |
void SimpleEntryImpl::CreationOperationComplete( |
- WeakPtr<SimpleIndex> index, |
- const CompletionCallback& completion_callback, |
- const std::string& key, |
Entry** out_entry, |
+ const CompletionCallback& completion_callback, |
SimpleSynchronousEntry* sync_entry) { |
+ DCHECK(io_thread_checker_.CalledOnValidThread()); |
if (!sync_entry) { |
completion_callback.Run(net::ERR_FAILED); |
// If OpenEntry failed, we must remove it from our index. |
- if (index) |
- index->Remove(key); |
+ if (index_) |
+ index_->Remove(key_); |
+ // The reference held by the Callback calling us will go out of scope and |
+ // delete |this| on leaving this scope. |
return; |
} |
- if (index) |
- index->Insert(sync_entry->key()); |
- *out_entry = new SimpleEntryImpl(sync_entry, index); |
+ // Adding a reference to self will keep |this| alive after the scope of our |
+ // Callback calling us is destroyed. |
+ AddRef(); // Balanced in Close(). |
+ synchronous_entry_ = sync_entry; |
+ SetSynchronousData(); |
+ if (index_) |
+ index_->Insert(key_); |
+ *out_entry = this; |
completion_callback.Run(net::OK); |
} |
-// static |
void SimpleEntryImpl::EntryOperationComplete( |
- base::WeakPtr<SimpleIndex> index, |
const CompletionCallback& completion_callback, |
- base::WeakPtr<SimpleEntryImpl> entry, |
- SimpleSynchronousEntry* sync_entry, |
int result) { |
- DCHECK(sync_entry); |
- if (index) { |
- if (result >= 0) |
- index->UpdateEntrySize(sync_entry->key(), sync_entry->GetFileSize()); |
- else |
- index->Remove(sync_entry->key()); |
- } |
- |
- if (entry) { |
- DCHECK(entry->synchronous_entry_in_use_by_worker_); |
- entry->synchronous_entry_in_use_by_worker_ = false; |
- entry->SetSynchronousData(); |
- } else { |
- // |entry| must have had Close() called while this operation was in flight. |
- // Since the simple cache now only supports one pending entry operation in |
- // flight at a time, it's safe to now call Close() on |sync_entry|. |
- WorkerPool::PostTask(FROM_HERE, |
- base::Bind(&SimpleSynchronousEntry::Close, |
- base::Unretained(sync_entry)), |
- true); |
+ DCHECK(io_thread_checker_.CalledOnValidThread()); |
+ DCHECK(synchronous_entry_); |
+ DCHECK(synchronous_entry_in_use_by_worker_); |
+ synchronous_entry_in_use_by_worker_ = false; |
+ SetSynchronousData(); |
+ if (index_) { |
+ if (result >= 0) { |
+ index_->UpdateEntrySize(synchronous_entry_->key(), |
+ synchronous_entry_->GetFileSize()); |
+ } else { |
+ index_->Remove(synchronous_entry_->key()); |
+ } |
} |
completion_callback.Run(result); |
} |