| 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);
|
| }
|
|
|