summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/file_stream_posix.cc11
-rw-r--r--net/base/file_stream_unittest.cc28
-rw-r--r--net/base/file_stream_win.cc9
-rw-r--r--net/base/test_completion_callback.h2
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;