Chromium Code Reviews| 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; |
| } |
| //----------------------------------------------------------------------------- |