Chromium Code Reviews| 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..22cbc956972cfc096089ca9021cd23100eb288bb 100644 |
| --- a/net/disk_cache/simple/simple_entry_impl.cc |
| +++ b/net/disk_cache/simple/simple_entry_impl.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/bind_helpers.h" |
| #include "base/callback.h" |
| #include "base/location.h" |
| +#include "base/logging.h" |
| #include "base/message_loop_proxy.h" |
| #include "base/threading/worker_pool.h" |
| #include "net/base/io_buffer.h" |
| @@ -30,11 +31,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(const scoped_refptr<SimpleIndex>& index, |
| const FilePath& path, |
| const std::string& key, |
| Entry** entry, |
| @@ -42,9 +42,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 +58,16 @@ int SimpleEntryImpl::OpenEntry(WeakPtr<SimpleIndex> index, |
| } |
| // static |
| -int SimpleEntryImpl::CreateEntry(WeakPtr<SimpleIndex> index, |
| +int SimpleEntryImpl::CreateEntry(const 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,12 +77,11 @@ int SimpleEntryImpl::CreateEntry(WeakPtr<SimpleIndex> index, |
| } |
| // static |
| -int SimpleEntryImpl::DoomEntry(WeakPtr<SimpleIndex> index, |
| +int SimpleEntryImpl::DoomEntry(const scoped_refptr<SimpleIndex>& index, |
| const FilePath& path, |
| const std::string& key, |
| const CompletionCallback& callback) { |
| - if (index) |
| - index->Remove(key); |
| + index->Remove(key); |
| WorkerPool::PostTask(FROM_HERE, |
| base::Bind(&SimpleSynchronousEntry::DoomEntry, path, key, |
| MessageLoopProxy::current(), 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,7 @@ void SimpleEntryImpl::Doom() { |
| void SimpleEntryImpl::Close() { |
|
gavinp
2013/04/20 07:28:33
***THREE*** In response to the callback from ***TW
|
| 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; |
| + Release(); // Balanced in CreationOperationCompleted(). |
|
gavinp
2013/04/20 07:28:33
***FOUR*** Close releases one ref on SimpleEntryIm
|
| } |
| std::string SimpleEntryImpl::GetKey() const { |
| @@ -147,12 +143,10 @@ int SimpleEntryImpl::ReadData(int index, |
| CHECK(false); |
| } |
| synchronous_entry_in_use_by_worker_ = true; |
| - if (index_) |
| - index_->UseIfExists(key_); |
| + 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_), |
| @@ -174,12 +168,10 @@ int SimpleEntryImpl::WriteData(int index, |
| CHECK(false); |
| } |
| synchronous_entry_in_use_by_worker_ = true; |
| - if (index_) |
| - index_->UseIfExists(key_); |
| + 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 +230,68 @@ 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(const scoped_refptr<SimpleIndex>& index, |
| + const base::FilePath& path, |
| + const std::string& key) |
| + : constructor_thread_(base::MessageLoopProxy::current()), |
| + 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_) { |
| + base::Closure close_sync_entry = |
| + base::Bind(&SimpleSynchronousEntry::Close, |
| + base::Unretained(synchronous_entry_)); |
| + // We aren't guaranteed to be able to run IO on our constructor thread, but |
| + // we are also not guaranteed to be allowed to run WorkerPool::PostTask on |
| + // our other threads. |
| + if (constructor_thread_->BelongsToCurrentThread()) |
| + WorkerPool::PostTask(FROM_HERE, close_sync_entry, true); |
| + else |
| + close_sync_entry.Run(); |
| + } |
| } |
| -// 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); |
| + 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 |
|
rvargas (doing something else)
2013/04/17 19:56:38
nit: "our callback calling us" -> the callback
gavinp
2013/04/18 09:12:41
Done.
|
| + // Callback calling us is destroyed. |
| + AddRef(); // Balanced in Close(). |
| + synchronous_entry_ = sync_entry; |
| + SetSynchronousData(); |
| + index_->Insert(key_); |
| + *out_entry = this; |
|
rvargas (doing something else)
2013/04/17 19:56:38
nit: I believe the "real" reason for Addref is tha
gavinp
2013/04/18 09:12:41
Done.
|
| 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(); |
| + DCHECK(io_thread_checker_.CalledOnValidThread()); |
| + DCHECK(synchronous_entry_); |
| + DCHECK(synchronous_entry_in_use_by_worker_); |
| + synchronous_entry_in_use_by_worker_ = false; |
| + SetSynchronousData(); |
| + if (result >= 0) { |
| + index_->UpdateEntrySize(synchronous_entry_->key(), |
| + synchronous_entry_->GetFileSize()); |
| } 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); |
| + index_->Remove(synchronous_entry_->key()); |
| } |
| completion_callback.Run(result); |
|
gavinp
2013/04/20 07:28:33
***TWO*** The IO thread runs the task posted just
|
| } |