| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/file_stream.h" | 5 #include "net/base/file_stream.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; | 43 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; |
| 44 return ERR_FAILED; | 44 return ERR_FAILED; |
| 45 } | 45 } |
| 46 } | 46 } |
| 47 | 47 |
| 48 // FileStream::AsyncContext ---------------------------------------------- | 48 // FileStream::AsyncContext ---------------------------------------------- |
| 49 | 49 |
| 50 class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { | 50 class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { |
| 51 public: | 51 public: |
| 52 AsyncContext(FileStream* owner) | 52 AsyncContext(FileStream* owner) |
| 53 : owner_(owner), context_(), callback_(NULL) { | 53 : owner_(owner), context_(), callback_(NULL), is_closing_(false) { |
| 54 context_.handler = this; | 54 context_.handler = this; |
| 55 } | 55 } |
| 56 ~AsyncContext(); | 56 ~AsyncContext(); |
| 57 | 57 |
| 58 void IOCompletionIsPending(CompletionCallback* callback); | 58 void IOCompletionIsPending(CompletionCallback* callback); |
| 59 | 59 |
| 60 OVERLAPPED* overlapped() { return &context_.overlapped; } | 60 OVERLAPPED* overlapped() { return &context_.overlapped; } |
| 61 CompletionCallback* callback() const { return callback_; } | 61 CompletionCallback* callback() const { return callback_; } |
| 62 | 62 |
| 63 private: | 63 private: |
| 64 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 64 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
| 65 DWORD bytes_read, DWORD error); | 65 DWORD bytes_read, DWORD error); |
| 66 | 66 |
| 67 FileStream* owner_; | 67 FileStream* owner_; |
| 68 MessageLoopForIO::IOContext context_; | 68 MessageLoopForIO::IOContext context_; |
| 69 CompletionCallback* callback_; | 69 CompletionCallback* callback_; |
| 70 bool is_closing_; |
| 70 }; | 71 }; |
| 71 | 72 |
| 72 FileStream::AsyncContext::~AsyncContext() { | 73 FileStream::AsyncContext::~AsyncContext() { |
| 74 is_closing_ = true; |
| 73 bool waited = false; | 75 bool waited = false; |
| 74 base::Time start = base::Time::Now(); | 76 base::Time start = base::Time::Now(); |
| 75 while (callback_) { | 77 while (callback_) { |
| 76 waited = true; | 78 waited = true; |
| 77 MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); | 79 MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); |
| 78 } | 80 } |
| 79 if (waited) { | 81 if (waited) { |
| 80 // We want to see if we block the message loop for too long. | 82 // We want to see if we block the message loop for too long. |
| 81 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose", base::Time::Now() - start); | 83 UMA_HISTOGRAM_TIMES("AsyncIO.FileStreamClose", base::Time::Now() - start); |
| 82 } | 84 } |
| 83 } | 85 } |
| 84 | 86 |
| 85 void FileStream::AsyncContext::IOCompletionIsPending( | 87 void FileStream::AsyncContext::IOCompletionIsPending( |
| 86 CompletionCallback* callback) { | 88 CompletionCallback* callback) { |
| 87 DCHECK(!callback_); | 89 DCHECK(!callback_); |
| 88 callback_ = callback; | 90 callback_ = callback; |
| 89 } | 91 } |
| 90 | 92 |
| 91 void FileStream::AsyncContext::OnIOCompleted( | 93 void FileStream::AsyncContext::OnIOCompleted( |
| 92 MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) { | 94 MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) { |
| 93 DCHECK(&context_ == context); | 95 DCHECK(&context_ == context); |
| 94 DCHECK(callback_); | 96 DCHECK(callback_); |
| 95 | 97 |
| 98 if (is_closing_) { |
| 99 callback_ = NULL; |
| 100 return; |
| 101 } |
| 102 |
| 96 int result = static_cast<int>(bytes_read); | 103 int result = static_cast<int>(bytes_read); |
| 97 if (error && error != ERROR_HANDLE_EOF) | 104 if (error && error != ERROR_HANDLE_EOF) |
| 98 result = MapErrorCode(error); | 105 result = MapErrorCode(error); |
| 99 | 106 |
| 100 if (bytes_read) | 107 if (bytes_read) |
| 101 IncrementOffset(&context->overlapped, bytes_read); | 108 IncrementOffset(&context->overlapped, bytes_read); |
| 102 | 109 |
| 103 CompletionCallback* temp = NULL; | 110 CompletionCallback* temp = NULL; |
| 104 std::swap(temp, callback_); | 111 std::swap(temp, callback_); |
| 105 temp->Run(result); | 112 temp->Run(result); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 DWORD error = GetLastError(); | 312 DWORD error = GetLastError(); |
| 306 LOG(WARNING) << "SetEndOfFile failed: " << error; | 313 LOG(WARNING) << "SetEndOfFile failed: " << error; |
| 307 return MapErrorCode(error); | 314 return MapErrorCode(error); |
| 308 } | 315 } |
| 309 | 316 |
| 310 // Success. | 317 // Success. |
| 311 return seek_position; | 318 return seek_position; |
| 312 } | 319 } |
| 313 | 320 |
| 314 } // namespace net | 321 } // namespace net |
| OLD | NEW |