Chromium Code Reviews| Index: net/disk_cache/simple/simple_backend_impl.cc |
| diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc |
| index 4aed36c78fc6c7db72720e3dcd84a380e72dca77..b9c93f26c84f986bf909c63b35caec49ca57190c 100644 |
| --- a/net/disk_cache/simple/simple_backend_impl.cc |
| +++ b/net/disk_cache/simple/simple_backend_impl.cc |
| @@ -33,6 +33,7 @@ |
| #include "net/disk_cache/simple/simple_synchronous_entry.h" |
| #include "net/disk_cache/simple/simple_util.h" |
| +using base::Callback; |
| using base::Closure; |
| using base::FilePath; |
| using base::MessageLoopProxy; |
| @@ -196,6 +197,32 @@ void CallCompletionCallback(const net::CompletionCallback& callback, |
| callback.Run(error_code); |
| } |
| +// See ChainOperationIntoClosure, below. |
| +void ChainOperationIntoClosureImpl( |
| + const base::WeakPtr<disk_cache::SimpleBackendImpl>& backend_weak_ptr, |
| + const Callback<int(const net::CompletionCallback&)>& to_chain_operation, |
| + const net::CompletionCallback& operation_callback, |
| + const Closure& closure) { |
| + if (backend_weak_ptr) { |
| + const int operation_result = to_chain_operation.Run(operation_callback); |
| + if (operation_result != net::ERR_IO_PENDING) |
| + operation_callback.Run(operation_result); |
| + } |
| + if (!closure.is_null()) |
| + closure.Run(); |
| +} |
| + |
| +// Returns a Closure that will first run |to_chain_operation|, returning its |
| +// result to |operation_callback|, and finally run |closure| if it is not null. |
| +Closure ChainOperationIntoClosure( |
| + const base::WeakPtr<disk_cache::SimpleBackendImpl>& backend_weak_ptr, |
| + const Callback<int(const net::CompletionCallback&)>& to_chain_operation, |
| + const net::CompletionCallback& operation_callback, |
| + const Closure& closure) { |
| + return base::Bind(&ChainOperationIntoClosureImpl, backend_weak_ptr, |
| + to_chain_operation, operation_callback, closure); |
| +} |
| + |
| void RecordIndexLoad(base::TimeTicks constructed_since, int result) { |
| const base::TimeDelta creation_to_index = base::TimeTicks::Now() - |
| constructed_since; |
| @@ -266,6 +293,19 @@ void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { |
| active_entries_.erase(entry->entry_hash()); |
| } |
| +void SimpleBackendImpl::OnDoomStart(const uint64 entry_hash) { |
| + DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash)); |
| + entries_pending_doom_.insert( |
| + base::hash_map<uint64, Closure>::value_type(entry_hash, Closure())); |
|
Philippe
2013/08/29 10:16:16
The closure that you create here will be the last
Philippe
2013/08/29 11:46:14
Or maybe instead do an erase() on the iterator ret
|
| +} |
| + |
| +void SimpleBackendImpl::OnDoomComplete(const uint64 entry_hash) { |
| + DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash)); |
| + Closure to_run_closure = entries_pending_doom_.find(entry_hash)->second; |
| + if (!to_run_closure.is_null()) |
| + to_run_closure.Run(); |
| +} |
| + |
| net::CacheType SimpleBackendImpl::GetCacheType() const { |
| return net::DISK_CACHE; |
| } |
| @@ -278,7 +318,20 @@ int32 SimpleBackendImpl::GetEntryCount() const { |
| int SimpleBackendImpl::OpenEntry(const std::string& key, |
| Entry** entry, |
| const CompletionCallback& callback) { |
| - scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); |
| + const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| + |
| + base::hash_map<uint64, base::Closure>::iterator |
| + it = entries_pending_doom_.find(entry_hash); |
| + if (it != entries_pending_doom_.end()) { |
| + Callback<int(const net::CompletionCallback&)> operation = |
| + base::Bind(&SimpleBackendImpl::OpenEntry, |
| + base::Unretained(this), key, entry); |
| + it->second = ChainOperationIntoClosure(AsWeakPtr(), operation, |
| + callback, it->second); |
| + return net::ERR_IO_PENDING; |
| + } |
| + scoped_refptr<SimpleEntryImpl> |
| + simple_entry = CreateOrFindActiveEntry(entry_hash, key); |
| CompletionCallback backend_callback = |
| base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, |
| AsWeakPtr(), |
| @@ -293,13 +346,35 @@ int SimpleBackendImpl::CreateEntry(const std::string& key, |
| Entry** entry, |
| const CompletionCallback& callback) { |
| DCHECK(key.size() > 0); |
| - scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); |
| + const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| + |
| + base::hash_map<uint64, base::Closure>::iterator |
| + it = entries_pending_doom_.find(entry_hash); |
| + if (it != entries_pending_doom_.end()) { |
| + Callback<int(const net::CompletionCallback&)> operation = |
| + base::Bind(&SimpleBackendImpl::CreateEntry, base::Unretained(this), key, entry); |
| + it->second = ChainOperationIntoClosure(AsWeakPtr(), operation, callback, it->second); |
| + return net::ERR_IO_PENDING; |
| + } |
| + scoped_refptr<SimpleEntryImpl> |
| + simple_entry = CreateOrFindActiveEntry(entry_hash, key); |
| return simple_entry->CreateEntry(entry, callback); |
| } |
| int SimpleBackendImpl::DoomEntry(const std::string& key, |
| const net::CompletionCallback& callback) { |
| - scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); |
| + const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| + |
| + base::hash_map<uint64, base::Closure>::iterator |
| + it = entries_pending_doom_.find(entry_hash); |
| + if (it != entries_pending_doom_.end()) { |
| + Callback<int(const net::CompletionCallback&)> operation = |
| + base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key); |
| + it->second = ChainOperationIntoClosure(AsWeakPtr(), operation, callback, it->second); |
| + return net::ERR_IO_PENDING; |
| + } |
| + scoped_refptr<SimpleEntryImpl> |
| + simple_entry = CreateOrFindActiveEntry(entry_hash, key); |
| return simple_entry->DoomEntry(callback); |
| } |
| @@ -421,8 +496,8 @@ SimpleBackendImpl::DiskStatResult SimpleBackendImpl::InitCacheStructureOnDisk( |
| } |
| scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( |
| + const uint64 entry_hash, |
| const std::string& key) { |
| - const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| std::pair<EntryMap::iterator, bool> insert_result = |
| active_entries_.insert(std::make_pair(entry_hash, |
| @@ -442,7 +517,7 @@ scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( |
| if (key != it->second->key()) { |
| it->second->Doom(); |
| DCHECK_EQ(0U, active_entries_.count(entry_hash)); |
| - return CreateOrFindActiveEntry(key); |
| + return CreateOrFindActiveEntry(entry_hash, key); |
| } |
| return make_scoped_refptr(it->second.get()); |
| } |