summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/backend_impl.cc
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 19:47:08 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 19:47:08 +0000
commitc4c32fd86f36a5d282424eb3a4876f0601f8f097 (patch)
tree580af26d6d69af57f7b1c63b9fbb97fc42ef1877 /net/disk_cache/backend_impl.cc
parenta5624da1a85ae1e2785d8534018329e5a144e1fc (diff)
downloadchromium_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.cc50
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) {