Index: net/disk_cache/rankings.cc |
=================================================================== |
--- net/disk_cache/rankings.cc (revision 21084) |
+++ net/disk_cache/rankings.cc (working copy) |
@@ -320,6 +320,7 @@ |
Trace("Remove 0x%x (0x%x 0x%x)", node->address().value(), node->Data()->next, |
node->Data()->prev); |
DCHECK(node->HasData()); |
+ InvalidateIterators(node); |
Addr next_addr(node->Data()->next); |
Addr prev_addr(node->Data()->prev); |
if (!next_addr.is_initialized() || next_addr.is_separate_file() || |
@@ -394,7 +395,6 @@ |
// entry. Otherwise we'll need reentrant transactions, which is an overkill. |
void Rankings::UpdateRank(CacheRankingsBlock* node, bool modified, List list) { |
Time start = Time::Now(); |
- NotAnIterator(node); |
Remove(node, list); |
Insert(node, modified, list); |
CACHE_UMA(AGE_MS, "UpdateRank", 0, start); |
@@ -574,6 +574,19 @@ |
TrackRankingsBlock(node, false); |
} |
+void Rankings::TrackRankingsBlock(CacheRankingsBlock* node, |
+ bool start_tracking) { |
+ if (!node) |
+ return; |
+ |
+ IteratorPair current(node->address().value(), node); |
+ |
+ if (start_tracking) |
+ iterators_.push_back(current); |
+ else |
+ iterators_.remove(current); |
+} |
+ |
int Rankings::SelfCheck() { |
int total = 0; |
for (int i = 0; i < LAST_ELEMENT; i++) { |
@@ -727,19 +740,6 @@ |
return false; |
} |
-void Rankings::TrackRankingsBlock(CacheRankingsBlock* node, |
- bool start_tracking) { |
- if (!node) |
- return; |
- |
- IteratorPair current(node->address().value(), node); |
- |
- if (start_tracking) |
- iterators_.push_back(current); |
- else |
- iterators_.remove(current); |
-} |
- |
// We expect to have just a few iterators at any given time, maybe two or three, |
// But we could have more than one pointing at the same mode. We walk the list |
// of cache iterators and update all that are pointing to the given node. |
@@ -747,7 +747,7 @@ |
CacheAddr address = node->address().value(); |
for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); |
++it) { |
- if (it->first == address) { |
+ if (it->first == address && it->second->HasData()) { |
CacheRankingsBlock* other = it->second; |
other->Data()->next = node->Data()->next; |
other->Data()->prev = node->Data()->prev; |
@@ -755,16 +755,14 @@ |
} |
} |
-void Rankings::NotAnIterator(CacheRankingsBlock* node) { |
-#ifdef NDEBUG |
- // This method is only enabled for debug builds. |
- return; |
-#endif |
+void Rankings::InvalidateIterators(CacheRankingsBlock* node) { |
CacheAddr address = node->address().value(); |
for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); |
++it) { |
- if (it->first == address) |
- NOTREACHED(); |
+ if (it->first == address) { |
+ LOG(WARNING) << "Invalidating iterator at 0x" << std::hex << address; |
+ it->second->Discard(); |
+ } |
} |
} |