diff options
-rw-r--r-- | net/base/file_stream_posix.cc | 11 | ||||
-rw-r--r-- | net/base/file_stream_unittest.cc | 28 | ||||
-rw-r--r-- | net/base/file_stream_win.cc | 9 | ||||
-rw-r--r-- | net/base/test_completion_callback.h | 2 |
4 files changed, 38 insertions, 12 deletions
diff --git a/net/base/file_stream_posix.cc b/net/base/file_stream_posix.cc index 7bc685c..fbfeb04 100644 --- a/net/base/file_stream_posix.cc +++ b/net/base/file_stream_posix.cc @@ -201,6 +201,8 @@ class FileStream::AsyncContext { int result_; CancelableCallbackTask* message_loop_task_; + bool is_closing_; + DISALLOW_COPY_AND_ASSIGN(AsyncContext); }; @@ -210,9 +212,11 @@ FileStream::AsyncContext::AsyncContext() background_io_completed_callback_( this, &AsyncContext::OnBackgroundIOCompleted), background_io_completed_(true, false), - message_loop_task_(NULL) {} + message_loop_task_(NULL), + is_closing_(false) {} FileStream::AsyncContext::~AsyncContext() { + is_closing_ = true; if (callback_) { // If |callback_| is non-NULL, that implies either the worker thread is // still running the IO task, or the completion callback is queued up on the @@ -272,6 +276,11 @@ void FileStream::AsyncContext::RunAsynchronousCallback() { message_loop_task_->Cancel(); message_loop_task_ = NULL; + if (is_closing_) { + callback_ = NULL; + return; + } + DCHECK(callback_); CompletionCallback* temp = NULL; std::swap(temp, callback_); diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc index 947aa3c..4b8b12b 100644 --- a/net/base/file_stream_unittest.cc +++ b/net/base/file_stream_unittest.cc @@ -184,10 +184,14 @@ TEST_F(FileStreamTest, AsyncRead_EarlyClose) { char buf[4]; rv = stream.Read(buf, arraysize(buf), &callback); stream.Close(); - if (rv == net::ERR_IO_PENDING) - rv = callback.WaitForResult(); - ASSERT_LE(0, rv); - EXPECT_EQ(std::string(kTestData, rv), std::string(buf, rv)); + if (rv < 0) { + EXPECT_EQ(net::ERR_IO_PENDING, rv); + // The callback should not be called if the request is cancelled. + MessageLoop::current()->RunAllPending(); + EXPECT_FALSE(callback.have_result()); + } else { + EXPECT_EQ(std::string(kTestData, rv), std::string(buf, rv)); + } } TEST_F(FileStreamTest, BasicRead_FromOffset) { @@ -360,12 +364,16 @@ TEST_F(FileStreamTest, AsyncWrite_EarlyClose) { kTestDataSize - total_bytes_written, &callback); stream.Close(); - if (rv == net::ERR_IO_PENDING) - rv = callback.WaitForResult(); - ASSERT_LT(0, rv); - ok = file_util::GetFileSize(temp_file_path(), &file_size); - EXPECT_TRUE(ok); - EXPECT_EQ(file_size, rv); + if (rv < 0) { + EXPECT_EQ(net::ERR_IO_PENDING, rv); + // The callback should not be called if the request is cancelled. + MessageLoop::current()->RunAllPending(); + EXPECT_FALSE(callback.have_result()); + } else { + ok = file_util::GetFileSize(temp_file_path(), &file_size); + EXPECT_TRUE(ok); + EXPECT_EQ(file_size, rv); + } } TEST_F(FileStreamTest, BasicWrite_FromOffset) { diff --git a/net/base/file_stream_win.cc b/net/base/file_stream_win.cc index caa636f..09ad88e 100644 --- a/net/base/file_stream_win.cc +++ b/net/base/file_stream_win.cc @@ -51,7 +51,7 @@ static int MapErrorCode(DWORD err) { class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { public: AsyncContext(FileStream* owner) - : owner_(owner), context_(), callback_(NULL) { + : owner_(owner), context_(), callback_(NULL), is_closing_(false) { context_.handler = this; } ~AsyncContext(); @@ -68,9 +68,11 @@ class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { FileStream* owner_; MessageLoopForIO::IOContext context_; CompletionCallback* callback_; + bool is_closing_; }; FileStream::AsyncContext::~AsyncContext() { + is_closing_ = true; bool waited = false; base::Time start = base::Time::Now(); while (callback_) { @@ -94,6 +96,11 @@ void FileStream::AsyncContext::OnIOCompleted( DCHECK(&context_ == context); DCHECK(callback_); + if (is_closing_) { + callback_ = NULL; + return; + } + int result = static_cast<int>(bytes_read); if (error && error != ERROR_HANDLE_EOF) result = MapErrorCode(error); diff --git a/net/base/test_completion_callback.h b/net/base/test_completion_callback.h index 3494646..65fec62 100644 --- a/net/base/test_completion_callback.h +++ b/net/base/test_completion_callback.h @@ -38,6 +38,8 @@ class TestCompletionCallback : public CallbackRunner< Tuple1<int> > { return result_; } + bool have_result() const { return have_result_; } + private: virtual void RunWithParams(const Tuple1<int>& params) { result_ = params.a; |