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 98efd701e5bb23b046fdafb9d558e253a87252d5..597c7297fbcbdca7fc0e0000c642af2858bec637 100644 |
| --- a/net/http/mock_http_cache.cc |
| +++ b/net/http/mock_http_cache.cc |
| @@ -11,6 +11,26 @@ |
| namespace { |
| +class OldCallbackRunner : public Task { |
|
awong
2011/12/08 22:35:11
Don't need this either I don't hitnk.
Bind(&OldCo
|
| + public: |
| + OldCallbackRunner(net::OldCompletionCallback* callback, int result) |
| + : callback_(callback), result_(result) {} |
| + virtual void Run() { |
| + callback_->Run(result_); |
| + } |
| + |
| + private: |
| + net::OldCompletionCallback* callback_; |
| + int result_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(OldCallbackRunner); |
| +}; |
| + |
| +void CompletionCallbackRunner( |
| + const net::CompletionCallback& callback, int result) { |
|
awong
2011/12/08 22:35:11
Don't need htis?
|
| + callback.Run(result); |
| +} |
| + |
| int GetTestModeForEntry(const std::string& key) { |
| // 'key' is prefixed with an identifier if it corresponds to a cached POST. |
| // Skip past that to locate the actual URL. |
| @@ -41,7 +61,8 @@ int g_test_mode = 0; |
| struct MockDiskEntry::CallbackInfo { |
| scoped_refptr<MockDiskEntry> entry; |
| - net::OldCompletionCallback* callback; |
| + net::OldCompletionCallback* old_callback; |
| + net::CompletionCallback callback; |
| int result; |
| }; |
| @@ -106,6 +127,30 @@ int MockDiskEntry::ReadData(int index, int offset, net::IOBuffer* buf, |
| return net::ERR_IO_PENDING; |
| } |
| +int MockDiskEntry::ReadData( |
| + int index, int offset, net::IOBuffer* buf, int buf_len, |
| + const net::CompletionCallback& callback) { |
| + DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); |
| + DCHECK(!callback.is_null()); |
| + |
| + if (fail_requests_) |
| + return net::ERR_CACHE_READ_FAILURE; |
| + |
| + if (offset < 0 || offset > static_cast<int>(data_[index].size())) |
| + return net::ERR_FAILED; |
| + if (static_cast<size_t>(offset) == data_[index].size()) |
| + return 0; |
| + |
| + int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); |
| + memcpy(buf->data(), &data_[index][offset], num); |
| + |
| + if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ) |
| + return num; |
| + |
| + CallbackLater(callback, num); |
| + return net::ERR_IO_PENDING; |
| +} |
| + |
| int MockDiskEntry::WriteData(int index, int offset, net::IOBuffer* buf, |
| int buf_len, net::OldCompletionCallback* callback, |
| bool truncate) { |
| @@ -132,6 +177,32 @@ int MockDiskEntry::WriteData(int index, int offset, net::IOBuffer* buf, |
| return net::ERR_IO_PENDING; |
| } |
| +int MockDiskEntry::WriteData( |
| + int index, int offset, net::IOBuffer* buf, int buf_len, |
| + const net::CompletionCallback& callback, bool truncate) { |
| + DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); |
| + DCHECK(truncate); |
| + DCHECK(!callback.is_null()); |
| + |
| + if (fail_requests_) { |
| + CallbackLater(callback, net::ERR_CACHE_READ_FAILURE); |
| + return net::ERR_IO_PENDING; |
| + } |
| + |
| + if (offset < 0 || offset > static_cast<int>(data_[index].size())) |
| + return net::ERR_FAILED; |
| + |
| + data_[index].resize(offset + buf_len); |
| + if (buf_len) |
| + memcpy(&data_[index][offset], buf->data(), buf_len); |
| + |
| + if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE) |
| + return buf_len; |
| + |
| + CallbackLater(callback, buf_len); |
| + return net::ERR_IO_PENDING; |
| +} |
| + |
| int MockDiskEntry::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| net::OldCompletionCallback* callback) { |
| DCHECK(callback); |
| @@ -264,7 +335,7 @@ void MockDiskEntry::IgnoreCallbacks(bool value) { |
| return; |
| ignore_callbacks_ = value; |
| if (!value) |
| - StoreAndDeliverCallbacks(false, NULL, NULL, 0); |
| + StoreAndDeliverCallbacks(false, NULL, NULL, net::CompletionCallback(), 0); |
| } |
| MockDiskEntry::~MockDiskEntry() { |
| @@ -275,13 +346,29 @@ MockDiskEntry::~MockDiskEntry() { |
| // leveraging the fact that this class is reference counted. |
| void MockDiskEntry::CallbackLater(net::OldCompletionCallback* callback, |
| int result) { |
| - if (ignore_callbacks_) |
| - return StoreAndDeliverCallbacks(true, this, callback, result); |
| + if (ignore_callbacks_) { |
| + StoreAndDeliverCallbacks(true, this, callback, |
| + net::CompletionCallback(), result); |
| + return; |
| + } |
| + |
| + MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| + &MockDiskEntry::RunOldCallback, this, callback, result)); |
| +} |
| + |
| +void MockDiskEntry::CallbackLater(const net::CompletionCallback& callback, |
| + int result) { |
| + if (ignore_callbacks_) { |
| + StoreAndDeliverCallbacks(true, this, NULL, callback, result); |
| + return; |
| + } |
| + |
| MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| &MockDiskEntry::RunCallback, this, callback, result)); |
| } |
| -void MockDiskEntry::RunCallback(net::OldCompletionCallback* callback, int result) { |
| +void MockDiskEntry::RunOldCallback( |
| + net::OldCompletionCallback* callback, int result) { |
| if (busy_) { |
| // This is kind of hacky, but controlling the behavior of just this entry |
| // from a test is sort of complicated. What we really want to do is |
| @@ -290,7 +377,7 @@ void MockDiskEntry::RunCallback(net::OldCompletionCallback* callback, int result |
| // this operation (already posted to the message loop)... and without |
| // just delaying for n mS (which may cause trouble with slow bots). So |
| // we re-post this operation (all async sparse IO operations will take two |
| - // trips trhough the message loop instead of one). |
| + // trips through the message loop instead of one). |
| if (!delayed_) { |
| delayed_ = true; |
| return CallbackLater(callback, result); |
| @@ -300,20 +387,44 @@ void MockDiskEntry::RunCallback(net::OldCompletionCallback* callback, int result |
| callback->Run(result); |
| } |
| +void MockDiskEntry::RunCallback( |
| + const net::CompletionCallback& callback, int result) { |
| + if (busy_) { |
| + // This is kind of hacky, but controlling the behavior of just this entry |
| + // from a test is sort of complicated. What we really want to do is |
| + // delay the delivery of a sparse IO operation a little more so that the |
| + // request start operation (async) will finish without seeing the end of |
| + // this operation (already posted to the message loop)... and without |
| + // just delaying for n mS (which may cause trouble with slow bots). So |
| + // we re-post this operation (all async sparse IO operations will take two |
| + // trips through the message loop instead of one). |
| + if (!delayed_) { |
| + delayed_ = true; |
| + return CallbackLater(callback, result); |
| + } |
| + } |
| + busy_ = false; |
| + callback.Run(result); |
| +} |
| + |
| // When |store| is true, stores the callback to be delivered later; otherwise |
| // delivers any callback previously stored. |
| // Static. |
| -void MockDiskEntry::StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry, |
| - net::OldCompletionCallback* callback, |
| - int result) { |
| +void MockDiskEntry::StoreAndDeliverCallbacks( |
| + bool store, MockDiskEntry* entry, |
| + net::OldCompletionCallback* old_callback, |
| + const net::CompletionCallback& callback, int result) { |
| static std::vector<CallbackInfo> callback_list; |
| if (store) { |
| - CallbackInfo c = {entry, callback, result}; |
| + CallbackInfo c = {entry, old_callback, callback, result}; |
| callback_list.push_back(c); |
| } else { |
| - for (size_t i = 0; i < callback_list.size(); i++) { |
| + for (size_t i = 0; i < callback_list.size(); ++i) { |
| CallbackInfo& c = callback_list[i]; |
| - c.entry->CallbackLater(c.callback, c.result); |
| + if (c.old_callback) |
| + c.entry->CallbackLater(c.old_callback, c.result); |
| + else |
| + c.entry->CallbackLater(c.callback, c.result); |
| } |
| callback_list.clear(); |
| } |
| @@ -325,20 +436,6 @@ bool MockDiskEntry::ignore_callbacks_ = false; |
| //----------------------------------------------------------------------------- |
| -class MockDiskCache::CallbackRunner : public Task { |
| - public: |
| - CallbackRunner(net::OldCompletionCallback* callback, int result) |
| - : callback_(callback), result_(result) {} |
| - virtual void Run() { |
| - callback_->Run(result_); |
| - } |
| - |
| - private: |
| - net::OldCompletionCallback* callback_; |
| - int result_; |
| - DISALLOW_COPY_AND_ASSIGN(CallbackRunner); |
| -}; |
| - |
| MockDiskCache::MockDiskCache() |
| : open_count_(0), create_count_(0), fail_requests_(false), |
| soft_failures_(false), double_create_check_(true) { |
| @@ -383,6 +480,38 @@ int MockDiskCache::OpenEntry(const std::string& key, disk_cache::Entry** entry, |
| return net::ERR_IO_PENDING; |
| } |
| +int MockDiskCache::OpenEntry(const std::string& key, disk_cache::Entry** entry, |
| + const net::CompletionCallback& callback) { |
| + DCHECK(!callback.is_null()); |
| + |
| + if (fail_requests_) |
| + return net::ERR_CACHE_OPEN_FAILURE; |
| + |
| + EntryMap::iterator it = entries_.find(key); |
| + if (it == entries_.end()) |
| + return net::ERR_CACHE_OPEN_FAILURE; |
| + |
| + if (it->second->is_doomed()) { |
| + it->second->Release(); |
| + entries_.erase(it); |
| + return net::ERR_CACHE_OPEN_FAILURE; |
| + } |
| + |
| + open_count_++; |
| + |
| + it->second->AddRef(); |
| + *entry = it->second; |
| + |
| + if (soft_failures_) |
| + it->second->set_fail_requests(); |
| + |
| + if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) |
| + return net::OK; |
| + |
| + CallbackLater(callback, net::OK); |
| + return net::ERR_IO_PENDING; |
| +} |
| + |
| int MockDiskCache::CreateEntry(const std::string& key, |
| disk_cache::Entry** entry, |
| net::OldCompletionCallback* callback) { |
| @@ -422,6 +551,46 @@ int MockDiskCache::CreateEntry(const std::string& key, |
| return net::ERR_IO_PENDING; |
| } |
| +int MockDiskCache::CreateEntry(const std::string& key, |
| + disk_cache::Entry** entry, |
| + const net::CompletionCallback& callback) { |
| + DCHECK(!callback.is_null()); |
| + |
| + if (fail_requests_) |
| + return net::ERR_CACHE_CREATE_FAILURE; |
| + |
| + EntryMap::iterator it = entries_.find(key); |
| + if (it != entries_.end()) { |
| + if (!it->second->is_doomed()) { |
| + if (double_create_check_) |
| + NOTREACHED(); |
| + else |
| + return net::ERR_CACHE_CREATE_FAILURE; |
| + } |
| + it->second->Release(); |
| + entries_.erase(it); |
| + } |
| + |
| + create_count_++; |
| + |
| + MockDiskEntry* new_entry = new MockDiskEntry(key); |
| + |
| + new_entry->AddRef(); |
| + entries_[key] = new_entry; |
| + |
| + new_entry->AddRef(); |
| + *entry = new_entry; |
| + |
| + if (soft_failures_) |
| + new_entry->set_fail_requests(); |
| + |
| + if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START) |
| + return net::OK; |
| + |
| + CallbackLater(callback, net::OK); |
| + return net::ERR_IO_PENDING; |
| +} |
| + |
| int MockDiskCache::DoomEntry(const std::string& key, |
| net::OldCompletionCallback* callback) { |
| DCHECK(callback); |
| @@ -478,7 +647,13 @@ void MockDiskCache::ReleaseAll() { |
| void MockDiskCache::CallbackLater(net::OldCompletionCallback* callback, |
| int result) { |
| MessageLoop::current()->PostTask(FROM_HERE, |
| - new CallbackRunner(callback, result)); |
| + new OldCallbackRunner(callback, result)); |
| +} |
| + |
| +void MockDiskCache::CallbackLater(const net::CompletionCallback& callback, |
| + int result) { |
| + MessageLoop::current()->PostTask( |
| + FROM_HERE, base::Bind(&CompletionCallbackRunner, callback, result)); |
|
awong
2011/12/08 22:35:11
I think you can just do Bind(callback, result) and
|
| } |
| //----------------------------------------------------------------------------- |
| @@ -501,9 +676,9 @@ MockHttpCache::MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory) |
| } |
| MockDiskCache* MockHttpCache::disk_cache() { |
| - TestOldCompletionCallback cb; |
| + net::TestCompletionCallback cb; |
| disk_cache::Backend* backend; |
| - int rv = http_cache_.GetBackend(&backend, &cb); |
| + int rv = http_cache_.GetBackend(&backend, cb.callback()); |
| rv = cb.GetResult(rv); |
| return (rv == net::OK) ? static_cast<MockDiskCache*>(backend) : NULL; |
| } |