| Index: net/disk_cache/eviction.cc
|
| ===================================================================
|
| --- net/disk_cache/eviction.cc (revision 21084)
|
| +++ net/disk_cache/eviction.cc (working copy)
|
| @@ -73,25 +73,29 @@
|
| if (new_eviction_)
|
| return TrimCacheV2(empty);
|
|
|
| - Trace("*** Trim Cache ***");
|
| if (backend_->disabled_ || trimming_)
|
| return;
|
|
|
| if (!empty && backend_->IsLoaded())
|
| return PostDelayedTrim();
|
|
|
| + Trace("*** Trim Cache ***");
|
| trimming_ = true;
|
| Time start = Time::Now();
|
| Rankings::ScopedRankingsBlock node(rankings_);
|
| Rankings::ScopedRankingsBlock next(rankings_,
|
| rankings_->GetPrev(node.get(), Rankings::NO_USE));
|
| - DCHECK(next.get());
|
| int target_size = empty ? 0 : max_size_;
|
| while (header_->num_bytes > target_size && next.get()) {
|
| + // The iterator could be invalidated within EvictEntry().
|
| + if (!next->HasData())
|
| + break;
|
| node.reset(next.release());
|
| next.reset(rankings_->GetPrev(node.get(), Rankings::NO_USE));
|
| if (!node->Data()->pointer || empty) {
|
| // This entry is not being used by anybody.
|
| + // Do NOT use node as an iterator after this point.
|
| + rankings_->TrackRankingsBlock(node.get(), false);
|
| if (!EvictEntry(node.get(), empty))
|
| continue;
|
|
|
| @@ -191,17 +195,12 @@
|
| }
|
|
|
| bool Eviction::EvictEntry(CacheRankingsBlock* node, bool empty) {
|
| - EntryImpl* entry;
|
| - bool dirty;
|
| - if (backend_->NewEntry(Addr(node->Data()->contents), &entry, &dirty)) {
|
| + EntryImpl* entry = backend_->GetEnumeratedEntry(node, true);
|
| + if (!entry) {
|
| Trace("NewEntry failed on Trim 0x%x", node->address().value());
|
| return false;
|
| }
|
|
|
| - if (node->Data()->pointer) {
|
| - // We ignore the failure; we're removing the entry anyway.
|
| - entry->Update();
|
| - }
|
| ReportTrimTimes(entry);
|
| if (empty || !new_eviction_) {
|
| entry->Doom();
|
| @@ -224,13 +223,13 @@
|
| // -----------------------------------------------------------------------
|
|
|
| void Eviction::TrimCacheV2(bool empty) {
|
| - Trace("*** Trim Cache ***");
|
| if (backend_->disabled_ || trimming_)
|
| return;
|
|
|
| if (!empty && backend_->IsLoaded())
|
| return PostDelayedTrim();
|
|
|
| + Trace("*** Trim Cache ***");
|
| trimming_ = true;
|
| Time start = Time::Now();
|
|
|
| @@ -270,11 +269,16 @@
|
| int target_size = empty ? 0 : max_size_;
|
| for (; list < kListsToSearch; list++) {
|
| while (header_->num_bytes > target_size && next[list].get()) {
|
| + // The iterator could be invalidated within EvictEntry().
|
| + if (!next[list]->HasData())
|
| + break;
|
| node.reset(next[list].release());
|
| next[list].reset(rankings_->GetPrev(node.get(),
|
| static_cast<Rankings::List>(list)));
|
| if (!node->Data()->pointer || empty) {
|
| // This entry is not being used by anybody.
|
| + // Do NOT use node as an iterator after this point.
|
| + rankings_->TrackRankingsBlock(node.get(), false);
|
| if (!EvictEntry(node.get(), empty))
|
| continue;
|
|
|
| @@ -419,6 +423,8 @@
|
| return false;
|
| }
|
|
|
| + // TODO(rvargas): figure out how to deal with corruption at this point (dirty
|
| + // entries that live in this list).
|
| if (node->Data()->pointer) {
|
| // We ignore the failure; we're removing the entry anyway.
|
| entry->Update();
|
|
|