Index: net/http/mock_http_cache.cc |
diff --git a/net/http/mock_http_cache.cc b/net/http/mock_http_cache.cc |
index 514cc4208f82c79b3cafb876ef027716fd69b09f..920b866dac787cb8839df1f21741d16c0976f3c3 100644 |
--- a/net/http/mock_http_cache.cc |
+++ b/net/http/mock_http_cache.cc |
@@ -74,7 +74,9 @@ MockDiskEntry::MockDiskEntry(const std::string& key) |
fail_sparse_requests_(false), |
busy_(false), |
delayed_(false), |
- cancel_(false) { |
+ cancel_(false), |
+ defer_op_(DEFER_NONE), |
+ resume_return_code_(0) { |
test_mode_ = GetTestModeForEntry(key); |
} |
@@ -125,10 +127,26 @@ int MockDiskEntry::ReadData(int index, |
if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) |
return num; |
+ // Pause and resume. |
+ if (defer_op_ == DEFER_READ) { |
+ defer_op_ = DEFER_NONE; |
+ resume_callback_ = callback; |
+ resume_return_code_ = num; |
+ return ERR_IO_PENDING; |
+ } |
+ |
CallbackLater(callback, num); |
return ERR_IO_PENDING; |
} |
+int MockDiskEntry::ResumeCacheOperation() { |
+ DCHECK(!resume_callback_.is_null()); |
+ CallbackLater(resume_callback_, resume_return_code_); |
+ resume_callback_.Reset(); |
+ resume_return_code_ = 0; |
+ return ERR_IO_PENDING; |
+} |
+ |
int MockDiskEntry::WriteData(int index, |
int offset, |
IOBuffer* buf, |
@@ -376,7 +394,9 @@ MockDiskCache::MockDiskCache() |
fail_requests_(false), |
soft_failures_(false), |
double_create_check_(true), |
- fail_sparse_requests_(false) {} |
+ fail_sparse_requests_(false), |
+ defer_op_(DEFER_NONE), |
+ resume_return_code_(0) {} |
MockDiskCache::~MockDiskCache() { |
ReleaseAll(); |
@@ -402,7 +422,12 @@ int MockDiskCache::OpenEntry(const std::string& key, |
return ERR_CACHE_OPEN_FAILURE; |
if (it->second->is_doomed()) { |
- it->second->Release(); |
+ // It's possible that the entry was doomed directly by invoking |
jkarlin
2017/07/12 16:15:54
There is a lot of new code here to track doomed en
shivanisha
2017/07/12 17:56:31
Keeping track of doomed_entries seems kind of good
shivanisha
2017/07/13 14:47:26
Let me know if you prefer to have the closure appr
|
+ // MockDiskEntry::Doom and thus was not inserted into the doomed_entries_ |
+ // map. Insert it now. |
+ if (doomed_entries_.count(key)) |
+ doomed_entries_[key]->Release(); |
+ doomed_entries_[key] = it->second; |
entries_.erase(it); |
return ERR_CACHE_OPEN_FAILURE; |
} |
@@ -437,7 +462,12 @@ int MockDiskCache::CreateEntry(const std::string& key, |
else |
return ERR_CACHE_CREATE_FAILURE; |
} |
- it->second->Release(); |
+ // It's possible that the entry was doomed directly by invoking |
+ // MockDiskEntry::Doom and thus was not inserted into the doomed_entries_ |
+ // map. Insert it now. |
+ if (doomed_entries_.count(key)) |
+ doomed_entries_[key]->Release(); |
+ doomed_entries_[key] = it->second; |
entries_.erase(it); |
} |
@@ -460,6 +490,14 @@ int MockDiskCache::CreateEntry(const std::string& key, |
if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) |
return OK; |
+ // Pause and resume. |
+ if (defer_op_ == DEFER_CREATE) { |
+ defer_op_ = DEFER_NONE; |
+ resume_callback_ = callback; |
+ resume_return_code_ = OK; |
+ return ERR_IO_PENDING; |
+ } |
+ |
CallbackLater(callback, OK); |
return ERR_IO_PENDING; |
} |
@@ -469,7 +507,9 @@ int MockDiskCache::DoomEntry(const std::string& key, |
DCHECK(!callback.is_null()); |
EntryMap::iterator it = entries_.find(key); |
if (it != entries_.end()) { |
- it->second->Release(); |
+ if (doomed_entries_.count(key)) |
+ doomed_entries_[key]->Release(); |
+ doomed_entries_[key] = it->second; |
entries_.erase(it); |
doomed_count_++; |
} |
@@ -526,10 +566,13 @@ size_t MockDiskCache::DumpMemoryStats( |
} |
void MockDiskCache::ReleaseAll() { |
- EntryMap::iterator it = entries_.begin(); |
- for (; it != entries_.end(); ++it) |
- it->second->Release(); |
+ for (auto entry : entries_) |
+ entry.second->Release(); |
entries_.clear(); |
+ |
+ for (auto doomed : doomed_entries_) |
+ doomed.second->Release(); |
+ doomed_entries_.clear(); |
} |
void MockDiskCache::CallbackLater(const CompletionCallback& callback, |
@@ -539,10 +582,60 @@ void MockDiskCache::CallbackLater(const CompletionCallback& callback, |
} |
bool MockDiskCache::IsDiskEntryDoomed(const std::string& key) { |
+ auto doomed_it = doomed_entries_.find(key); |
+ if (doomed_it != doomed_entries_.end()) |
+ return true; |
+ |
+ auto it = entries_.find(key); |
+ if (it != entries_.end()) |
+ return it->second->is_doomed(); |
+ |
+ return false; |
+} |
+ |
+bool MockDiskCache::IsDiskEntryNotDoomed(const std::string& key) { |
+ auto it = entries_.find(key); |
+ if (it != entries_.end()) |
+ return !it->second->is_doomed(); |
+ |
+ return false; |
+} |
+ |
+int MockDiskCache::ResumeCacheOperation() { |
+ DCHECK(!resume_callback_.is_null()); |
+ CallbackLater(resume_callback_, resume_return_code_); |
+ resume_callback_.Reset(); |
+ resume_return_code_ = 0; |
+ return ERR_IO_PENDING; |
+} |
+ |
+void MockDiskCache::SetDefer(const std::string& key, const DeferOp defer_op) { |
auto it = entries_.find(key); |
if (it == entries_.end()) |
- return false; |
- return it->second->is_doomed(); |
+ return; |
+ it->second->SetDefer(defer_op); |
+} |
+ |
+int MockDiskCache::ResumeCacheOperation(const std::string& key) { |
+ auto it = entries_.find(key); |
+ if (it != entries_.end()) |
+ return it->second->ResumeCacheOperation(); |
+ |
+ return ERR_UNEXPECTED; |
+} |
+ |
+int MockDiskCache::ResumeDoomedEntryCacheOperation(const std::string& key) { |
+ auto doomed_it = doomed_entries_.find(key); |
+ if (doomed_it != doomed_entries_.end()) |
+ return doomed_it->second->ResumeCacheOperation(); |
+ |
+ auto it = entries_.find(key); |
+ if (it != entries_.end()) { |
+ DCHECK(it->second->is_doomed()); |
+ return it->second->ResumeCacheOperation(); |
+ } |
+ |
+ return ERR_UNEXPECTED; |
} |
//----------------------------------------------------------------------------- |