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 7cf4ea63aee4d9414828c8ac041ff00e27843c9d..b474abfd404399f2fa094943424d8881655dab9e 100644 |
| --- a/net/disk_cache/simple/simple_entry_impl.cc |
| +++ b/net/disk_cache/simple/simple_entry_impl.cc |
| @@ -42,9 +42,12 @@ 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); |
| + *entry = new_entry.get(); |
|
rvargas (doing something else)
2013/04/15 22:07:27
Although strictly not required by anything, it is
gavinp
2013/04/16 08:41:55
Done.
|
| SynchronousCreationCallback sync_creation_callback = |
| base::Bind(&SimpleEntryImpl::CreationOperationComplete, |
| - index, callback, key, entry); |
| + new_entry, callback); |
| WorkerPool::PostTask(FROM_HERE, |
| base::Bind(&SimpleSynchronousEntry::OpenEntry, path, |
| key, MessageLoopProxy::current(), |
| @@ -61,9 +64,12 @@ int SimpleEntryImpl::CreateEntry(WeakPtr<SimpleIndex> index, |
| const std::string& key, |
| Entry** entry, |
| const CompletionCallback& callback) { |
| + scoped_refptr<SimpleEntryImpl> new_entry = |
| + new SimpleEntryImpl(index, path, key); |
| + *entry = new_entry.get(); |
| SynchronousCreationCallback sync_creation_callback = |
| base::Bind(&SimpleEntryImpl::CreationOperationComplete, |
| - index, callback, key, entry); |
| + new_entry, callback); |
| WorkerPool::PostTask(FROM_HERE, |
| base::Bind(&SimpleSynchronousEntry::CreateEntry, path, |
| key, MessageLoopProxy::current(), |
| @@ -88,6 +94,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 +108,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; |
| + DCHECK_EQ(this, self_.get()); |
| + bool in_use = synchronous_entry_in_use_by_worker_; |
| + DCHECK((in_use && !HasOneRef()) || (!in_use && HasOneRef())); |
| + self_ = NULL; |
| + // 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. |
| + DCHECK(!in_use || (in_use && HasOneRef())); |
|
rvargas (doing something else)
2013/04/15 22:07:27
if (in_use)
DCHECK();
gavinp
2013/04/16 08:41:55
Done.
|
| } |
| std::string SimpleEntryImpl::GetKey() const { |
| @@ -150,8 +156,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_), |
| @@ -176,8 +181,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_), |
| @@ -236,74 +240,70 @@ 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(WeakPtr<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, |
| 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_); |
| return; |
| } |
| - if (index) |
| - index->Insert(sync_entry->key()); |
| - *out_entry = new SimpleEntryImpl(sync_entry, index); |
| + Initialize(sync_entry); |
|
rvargas (doing something else)
2013/04/15 22:07:27
Why do you need a self_ reference? It is created a
gavinp
2013/04/16 08:41:55
At least self_ advertises that it doesn't leak ref
|
| + if (index_) |
| + index_->Insert(key_); |
| 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); |
| } |
| +void SimpleEntryImpl::Initialize( |
| + SimpleSynchronousEntry* sync_entry) { |
| + DCHECK(io_thread_checker_.CalledOnValidThread()); |
| + self_ = this; |
| + synchronous_entry_ = sync_entry; |
| + SetSynchronousData(); |
| +} |
| + |
| void SimpleEntryImpl::SetSynchronousData() { |
| DCHECK(io_thread_checker_.CalledOnValidThread()); |
| DCHECK(!synchronous_entry_in_use_by_worker_); |