diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-07 19:47:08 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-07 19:47:08 +0000 |
commit | c4c32fd86f36a5d282424eb3a4876f0601f8f097 (patch) | |
tree | 580af26d6d69af57f7b1c63b9fbb97fc42ef1877 /net/disk_cache/backend_impl.cc | |
parent | a5624da1a85ae1e2785d8534018329e5a144e1fc (diff) | |
download | chromium_src-c4c32fd86f36a5d282424eb3a4876f0601f8f097.zip chromium_src-c4c32fd86f36a5d282424eb3a4876f0601f8f097.tar.gz chromium_src-c4c32fd86f36a5d282424eb3a4876f0601f8f097.tar.bz2 |
Disk cache: Keep a map of all open entries.
We still have a few crashes when for some reason we believe
an entry is not dirty and we follow the pointer stored by
its rankings node only to crash while accessing the memory.
I have no explanation to why the dirty id matches the current
one (a page boundary issue maybe?), but having a map with all
open entries solves the issue of having to follow pointers
from disk.
BUG=15596, b/1120346
TEST=unittests
Review URL: http://codereview.chromium.org/149218
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20067 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache/backend_impl.cc')
-rw-r--r-- | net/disk_cache/backend_impl.cc | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc index d41efe8..3cd3cc2 100644 --- a/net/disk_cache/backend_impl.cc +++ b/net/disk_cache/backend_impl.cc @@ -426,6 +426,9 @@ bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { return false; } + // We are not failing the operation; let's add this to the map. + open_entries_[entry_address.value()] = cache_entry; + if (parent.get()) parent->SetNextAddress(entry_address); @@ -720,11 +723,26 @@ void BackendImpl::RemoveEntry(EntryImpl* entry) { DecreaseNumEntries(); } -void BackendImpl::CacheEntryDestroyed() { +void BackendImpl::CacheEntryDestroyed(Addr address) { + EntriesMap::iterator it = open_entries_.find(address.value()); + if (it != open_entries_.end()) + open_entries_.erase(it); DecreaseNumRefs(); } -int32 BackendImpl::GetCurrentEntryId() { +bool BackendImpl::IsOpen(CacheRankingsBlock* rankings) const { + DCHECK(rankings->HasData()); + EntriesMap::const_iterator it = + open_entries_.find(rankings->Data()->contents); + if (it != open_entries_.end()) { + // We have this entry in memory. + return rankings->Data()->pointer == it->second; + } + + return false; +} + +int32 BackendImpl::GetCurrentEntryId() const { return data_->header.this_id; } @@ -1035,6 +1053,16 @@ void BackendImpl::PrepareForRestart() { } int BackendImpl::NewEntry(Addr address, EntryImpl** entry, bool* dirty) { + EntriesMap::iterator it = open_entries_.find(address.value()); + if (it != open_entries_.end()) { + // Easy job. This entry is already in memory. + EntryImpl* this_entry = it->second; + this_entry->AddRef(); + *entry = this_entry; + *dirty = false; + return 0; + } + scoped_refptr<EntryImpl> cache_entry(new EntryImpl(this, address)); IncreaseNumRefs(); *entry = NULL; @@ -1064,6 +1092,10 @@ int BackendImpl::NewEntry(Addr address, EntryImpl** entry, bool* dirty) { if (!rankings_.SanityCheck(cache_entry->rankings(), false)) return ERR_INVALID_LINKS; + // We only add clean entries to the map. + if (!*dirty) + open_entries_[address.value()] = cache_entry; + cache_entry.swap(entry); return 0; } @@ -1119,11 +1151,17 @@ EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, } if (cache_entry->IsSameEntry(key, hash)) { - cache_entry = EntryImpl::Update(cache_entry); + if (!cache_entry->Update()) { + cache_entry->Release(); + cache_entry = NULL; + } found = true; break; } - cache_entry = EntryImpl::Update(cache_entry); + if (!cache_entry->Update()) { + cache_entry->Release(); + cache_entry = NULL; + } if (parent_entry) parent_entry->Release(); parent_entry = cache_entry; @@ -1279,9 +1317,11 @@ EntryImpl* BackendImpl::GetEnumeratedEntry(CacheRankingsBlock* next) { return NULL; } + if (!entry->Update()) + return NULL; entry.swap(&temp); - return EntryImpl::Update(temp); // Update returns an adref'd entry. + return temp; } bool BackendImpl::ResurrectEntry(EntryImpl* deleted_entry, Entry** entry) { |