diff options
-rw-r--r-- | net/base/test_completion_callback.h | 15 | ||||
-rw-r--r-- | net/disk_cache/entry_impl.cc | 1 | ||||
-rw-r--r-- | net/disk_cache/entry_unittest.cc | 65 | ||||
-rw-r--r-- | net/disk_cache/in_flight_backend_io.cc | 1 | ||||
-rw-r--r-- | net/spdy/spdy_websocket_stream_spdy2_unittest.cc | 2 | ||||
-rw-r--r-- | net/spdy/spdy_websocket_stream_spdy3_unittest.cc | 2 |
6 files changed, 66 insertions, 20 deletions
diff --git a/net/base/test_completion_callback.h b/net/base/test_completion_callback.h index 25c9676..6d44abe 100644 --- a/net/base/test_completion_callback.h +++ b/net/base/test_completion_callback.h @@ -47,10 +47,7 @@ template <typename R> class TestCompletionCallbackTemplate : public TestCompletionCallbackBaseInternal { public: - void SetResult(R result) { - result_ = result; - DidSetResult(); - } + virtual ~TestCompletionCallbackTemplate() {} R WaitForResult() { TestCompletionCallbackBaseInternal::WaitForResult(); @@ -64,6 +61,12 @@ class TestCompletionCallbackTemplate } protected: + // Override this method to gain control as the callback is running. + virtual void SetResult(R result) { + result_ = result; + DidSetResult(); + } + TestCompletionCallbackTemplate() : result_(R()) {} R result_; @@ -83,7 +86,7 @@ typedef internal::TestCompletionCallbackTemplate<int64> class TestCompletionCallback : public TestCompletionCallbackBase { public: TestCompletionCallback(); - ~TestCompletionCallback(); + virtual ~TestCompletionCallback(); const CompletionCallback& callback() const { return callback_; } @@ -96,7 +99,7 @@ class TestCompletionCallback : public TestCompletionCallbackBase { class TestInt64CompletionCallback : public TestInt64CompletionCallbackBase { public: TestInt64CompletionCallback(); - ~TestInt64CompletionCallback(); + virtual ~TestInt64CompletionCallback(); const Int64CompletionCallback& callback() const { return callback_; } diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc index b79230f..6155aa1 100644 --- a/net/disk_cache/entry_impl.cc +++ b/net/disk_cache/entry_impl.cc @@ -64,6 +64,7 @@ void SyncCallback::OnFileIOComplete(int bytes_copied) { disk_cache::CreateNetLogReadWriteCompleteCallback(bytes_copied)); } entry_->ReportIOTime(disk_cache::EntryImpl::kAsyncIO, start_); + buf_ = NULL; // Release the buffer before invoking the callback. callback_.Run(bytes_copied); } entry_->Release(); diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc index 8168ae8..1094f06 100644 --- a/net/disk_cache/entry_unittest.cc +++ b/net/disk_cache/entry_unittest.cc @@ -35,6 +35,7 @@ class DiskCacheEntryTest : public DiskCacheTestWithCache { void InternalAsyncIO(); void ExternalSyncIO(); void ExternalAsyncIO(); + void ReleaseBuffer(); void StreamAccess(); void GetKey(); void GetTimes(); @@ -510,6 +511,53 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyExternalAsyncIO) { ExternalAsyncIO(); } +// Makes sure that the buffer is not referenced when the callback runs. +class ReleaseBufferCompletionCallback: public net::TestCompletionCallback { + public: + explicit ReleaseBufferCompletionCallback(net::IOBuffer* buffer) + : buffer_(buffer) { + } + + private: + virtual void SetResult(int result) OVERRIDE { + if (!buffer_->HasOneRef()) + result = net::ERR_FAILED; + TestCompletionCallback::SetResult(result); + } + + net::IOBuffer* buffer_; + DISALLOW_COPY_AND_ASSIGN(ReleaseBufferCompletionCallback); +}; + +// Tests that IOBuffers are not referenced after IO completes. +void DiskCacheEntryTest::ReleaseBuffer() { + disk_cache::Entry* entry = NULL; + ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); + ASSERT_TRUE(NULL != entry); + + const int kBufferSize = 1024; + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); + CacheTestFillBuffer(buffer->data(), kBufferSize, false); + + ReleaseBufferCompletionCallback cb(buffer); + int rv = entry->WriteData(0, 0, buffer, kBufferSize, cb.callback(), false); + EXPECT_EQ(kBufferSize, cb.GetResult(rv)); + entry->Close(); +} + +TEST_F(DiskCacheEntryTest, ReleaseBuffer) { + SetDirectMode(); + InitCache(); + cache_impl_->SetFlags(disk_cache::kNoBuffering); + ReleaseBuffer(); +} + +TEST_F(DiskCacheEntryTest, MemoryOnlyReleaseBuffer) { + SetMemoryOnlyMode(); + InitCache(); + ReleaseBuffer(); +} + void DiskCacheEntryTest::StreamAccess() { disk_cache::Entry* entry = NULL; ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); @@ -1783,29 +1831,22 @@ TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) { } // A CompletionCallback wrapper that deletes the cache from within the callback. -// The way an CompletionCallback works means that all tasks (even new ones) +// The way a CompletionCallback works means that all tasks (even new ones) // are executed by the message loop before returning to the caller so the only // way to simulate a race is to execute what we want on the callback. -class SparseTestCompletionCallback: public net::TestCompletionCallbackBase { +class SparseTestCompletionCallback: public net::TestCompletionCallback { public: explicit SparseTestCompletionCallback(disk_cache::Backend* cache) - : cache_(cache), - ALLOW_THIS_IN_INITIALIZER_LIST(callback_( - base::Bind(&SparseTestCompletionCallback::OnComplete, - base::Unretained(this)))) { + : cache_(cache) { } - const net::CompletionCallback& callback() const { return callback_; } - private: - void OnComplete(int result) { + virtual void SetResult(int result) OVERRIDE { delete cache_; - SetResult(result); + TestCompletionCallback::SetResult(result); } disk_cache::Backend* cache_; - net::CompletionCallback callback_; - DISALLOW_COPY_AND_ASSIGN(SparseTestCompletionCallback); }; diff --git a/net/disk_cache/in_flight_backend_io.cc b/net/disk_cache/in_flight_backend_io.cc index 1dd8669..163c7f6 100644 --- a/net/disk_cache/in_flight_backend_io.cc +++ b/net/disk_cache/in_flight_backend_io.cc @@ -322,6 +322,7 @@ void BackendIO::ExecuteEntryOperation() { NOTREACHED() << "Invalid Operation"; result_ = net::ERR_UNEXPECTED; } + buf_ = NULL; if (result_ != net::ERR_IO_PENDING) NotifyController(); } diff --git a/net/spdy/spdy_websocket_stream_spdy2_unittest.cc b/net/spdy/spdy_websocket_stream_spdy2_unittest.cc index 36cc317..5f468c9 100644 --- a/net/spdy/spdy_websocket_stream_spdy2_unittest.cc +++ b/net/spdy/spdy_websocket_stream_spdy2_unittest.cc @@ -177,7 +177,7 @@ class SpdyWebSocketStreamSpdy2Test : public testing::Test { } void DoSync(SpdyWebSocketStreamEvent* event) { - sync_callback_.SetResult(OK); + sync_callback_.callback().Run(OK); } protected: diff --git a/net/spdy/spdy_websocket_stream_spdy3_unittest.cc b/net/spdy/spdy_websocket_stream_spdy3_unittest.cc index 40d80c2..5a21e66 100644 --- a/net/spdy/spdy_websocket_stream_spdy3_unittest.cc +++ b/net/spdy/spdy_websocket_stream_spdy3_unittest.cc @@ -177,7 +177,7 @@ class SpdyWebSocketStreamSpdy3Test : public testing::Test { } void DoSync(SpdyWebSocketStreamEvent* event) { - sync_callback_.SetResult(OK); + sync_callback_.callback().Run(OK); } protected: |