| 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 9ae613fcc7d91244596d6354811b4188091f95c9..ba86874bba9d9c7b8acd9433c1e0a72f7d9b770f 100644
|
| --- a/net/disk_cache/simple/simple_backend_impl.cc
|
| +++ b/net/disk_cache/simple/simple_backend_impl.cc
|
| @@ -34,6 +34,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;
|
| @@ -200,6 +201,28 @@ void CallCompletionCallback(const net::CompletionCallback& callback,
|
| callback.Run(error_code);
|
| }
|
|
|
| +// See ChainOperationIntoClosure, below.
|
| +void ChainOperationIntoClosureImpl(
|
| + const Callback<int(const net::CompletionCallback&)>& to_chain_operation,
|
| + const net::CompletionCallback& operation_callback,
|
| + const Closure& closure) {
|
| + 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 Callback<int(const net::CompletionCallback&)>& to_chain_operation,
|
| + const net::CompletionCallback& operation_callback,
|
| + const Closure& closure) {
|
| + return base::Bind(&ChainOperationIntoClosureImpl, to_chain_operation,
|
| + operation_callback, closure);
|
| +}
|
| +
|
| void RecordIndexLoad(net::CacheType cache_type,
|
| base::TimeTicks constructed_since,
|
| int result) {
|
| @@ -274,6 +297,22 @@ void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) {
|
| active_entries_.erase(entry->entry_hash());
|
| }
|
|
|
| +void SimpleBackendImpl::OnDoomStart(uint64 entry_hash) {
|
| + DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash));
|
| + entries_pending_doom_.insert(std::make_pair(entry_hash, Closure()));
|
| +}
|
| +
|
| +void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) {
|
| + DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash));
|
| + base::hash_map<uint64, base::Closure>::iterator it =
|
| + entries_pending_doom_.find(entry_hash);
|
| + Closure to_run_closure = it->second;
|
| + entries_pending_doom_.erase(it);
|
| +
|
| + if (!to_run_closure.is_null())
|
| + to_run_closure.Run();
|
| +}
|
| +
|
| net::CacheType SimpleBackendImpl::GetCacheType() const {
|
| return net::DISK_CACHE;
|
| }
|
| @@ -286,7 +325,19 @@ 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(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(),
|
| @@ -301,14 +352,37 @@ int SimpleBackendImpl::CreateEntry(const std::string& key,
|
| Entry** entry,
|
| const CompletionCallback& callback) {
|
| DCHECK_LT(0u, key.size());
|
| - 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(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);
|
| - return simple_entry->DoomEntry(callback);
|
| + 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(operation, callback, it->second);
|
| + return net::ERR_IO_PENDING;
|
| + }
|
| + scoped_refptr<SimpleEntryImpl> simple_entry =
|
| + CreateOrFindActiveEntry(entry_hash, key);
|
| +return simple_entry->DoomEntry(callback);
|
| }
|
|
|
| int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) {
|
| @@ -429,9 +503,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,
|
| base::WeakPtr<SimpleEntryImpl>()));
|
| @@ -450,7 +523,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());
|
| }
|
|
|