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 |