| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ | 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ |
| 6 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ | 6 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ |
| 7 | 7 |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 | 9 |
| 10 #include <list> | 10 #include <list> |
| 11 | 11 |
| 12 #include "base/base_export.h" | 12 #include "base/base_export.h" |
| 13 #include "base/message_loop/message_pump.h" | 13 #include "base/message_loop/message_pump.h" |
| 14 #include "base/observer_list.h" | |
| 15 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 16 #include "base/win/scoped_handle.h" | 15 #include "base/win/scoped_handle.h" |
| 17 | 16 |
| 18 namespace base { | 17 namespace base { |
| 19 | 18 |
| 20 // MessagePumpWin serves as the base for specialized versions of the MessagePump | 19 // MessagePumpWin serves as the base for specialized versions of the MessagePump |
| 21 // for Windows. It provides basic functionality like handling of observers and | 20 // for Windows. It provides basic functionality like handling of observers and |
| 22 // controlling the lifetime of the message pump. | 21 // controlling the lifetime of the message pump. |
| 23 class BASE_EXPORT MessagePumpWin : public MessagePump { | 22 class BASE_EXPORT MessagePumpWin : public MessagePump { |
| 24 public: | 23 public: |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 public: | 228 public: |
| 230 virtual ~IOHandler() {} | 229 virtual ~IOHandler() {} |
| 231 // This will be called once the pending IO operation associated with | 230 // This will be called once the pending IO operation associated with |
| 232 // |context| completes. |error| is the Win32 error code of the IO operation | 231 // |context| completes. |error| is the Win32 error code of the IO operation |
| 233 // (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero | 232 // (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero |
| 234 // on error. | 233 // on error. |
| 235 virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered, | 234 virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered, |
| 236 DWORD error) = 0; | 235 DWORD error) = 0; |
| 237 }; | 236 }; |
| 238 | 237 |
| 239 // An IOObserver is an object that receives IO notifications from the | |
| 240 // MessagePump. | |
| 241 // | |
| 242 // NOTE: An IOObserver implementation should be extremely fast! | |
| 243 class IOObserver { | |
| 244 public: | |
| 245 IOObserver() {} | |
| 246 | |
| 247 virtual void WillProcessIOEvent() = 0; | |
| 248 virtual void DidProcessIOEvent() = 0; | |
| 249 | |
| 250 protected: | |
| 251 virtual ~IOObserver() {} | |
| 252 }; | |
| 253 | |
| 254 // The extended context that should be used as the base structure on every | 238 // The extended context that should be used as the base structure on every |
| 255 // overlapped IO operation. |handler| must be set to the registered IOHandler | 239 // overlapped IO operation. |handler| must be set to the registered IOHandler |
| 256 // for the given file when the operation is started, and it can be set to NULL | 240 // for the given file when the operation is started, and it can be set to NULL |
| 257 // before the operation completes to indicate that the handler should not be | 241 // before the operation completes to indicate that the handler should not be |
| 258 // called anymore, and instead, the IOContext should be deleted when the OS | 242 // called anymore, and instead, the IOContext should be deleted when the OS |
| 259 // notifies the completion of this operation. Please remember that any buffers | 243 // notifies the completion of this operation. Please remember that any buffers |
| 260 // involved with an IO operation should be around until the callback is | 244 // involved with an IO operation should be around until the callback is |
| 261 // received, so this technique can only be used for IO that do not involve | 245 // received, so this technique can only be used for IO that do not involve |
| 262 // additional buffers (other than the overlapped structure itself). | 246 // additional buffers (other than the overlapped structure itself). |
| 263 struct IOContext { | 247 struct IOContext { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 287 // up to |timeout| milliseconds. Return true if any IO operation completed, | 271 // up to |timeout| milliseconds. Return true if any IO operation completed, |
| 288 // regardless of the involved handler, and false if the timeout expired. If | 272 // regardless of the involved handler, and false if the timeout expired. If |
| 289 // the completion port received any message and the involved IO handler | 273 // the completion port received any message and the involved IO handler |
| 290 // matches |filter|, the callback is called before returning from this code; | 274 // matches |filter|, the callback is called before returning from this code; |
| 291 // if the handler is not the one that we are looking for, the callback will | 275 // if the handler is not the one that we are looking for, the callback will |
| 292 // be postponed for another time, so reentrancy problems can be avoided. | 276 // be postponed for another time, so reentrancy problems can be avoided. |
| 293 // External use of this method should be reserved for the rare case when the | 277 // External use of this method should be reserved for the rare case when the |
| 294 // caller is willing to allow pausing regular task dispatching on this thread. | 278 // caller is willing to allow pausing regular task dispatching on this thread. |
| 295 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); | 279 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); |
| 296 | 280 |
| 297 void AddIOObserver(IOObserver* obs); | |
| 298 void RemoveIOObserver(IOObserver* obs); | |
| 299 | |
| 300 private: | 281 private: |
| 301 struct IOItem { | 282 struct IOItem { |
| 302 IOHandler* handler; | 283 IOHandler* handler; |
| 303 IOContext* context; | 284 IOContext* context; |
| 304 DWORD bytes_transfered; | 285 DWORD bytes_transfered; |
| 305 DWORD error; | 286 DWORD error; |
| 306 | 287 |
| 307 // In some cases |context| can be a non-pointer value casted to a pointer. | 288 // In some cases |context| can be a non-pointer value casted to a pointer. |
| 308 // |has_valid_io_context| is true if |context| is a valid IOContext | 289 // |has_valid_io_context| is true if |context| is a valid IOContext |
| 309 // pointer, and false otherwise. | 290 // pointer, and false otherwise. |
| 310 bool has_valid_io_context; | 291 bool has_valid_io_context; |
| 311 }; | 292 }; |
| 312 | 293 |
| 313 void DoRunLoop() override; | 294 void DoRunLoop() override; |
| 314 void WaitForWork(); | 295 void WaitForWork(); |
| 315 bool MatchCompletedIOItem(IOHandler* filter, IOItem* item); | 296 bool MatchCompletedIOItem(IOHandler* filter, IOItem* item); |
| 316 bool GetIOItem(DWORD timeout, IOItem* item); | 297 bool GetIOItem(DWORD timeout, IOItem* item); |
| 317 bool ProcessInternalIOItem(const IOItem& item); | 298 bool ProcessInternalIOItem(const IOItem& item); |
| 318 void WillProcessIOEvent(); | |
| 319 void DidProcessIOEvent(); | |
| 320 | 299 |
| 321 // Converts an IOHandler pointer to a completion port key. | 300 // Converts an IOHandler pointer to a completion port key. |
| 322 // |has_valid_io_context| specifies whether completion packets posted to | 301 // |has_valid_io_context| specifies whether completion packets posted to |
| 323 // |handler| will have valid OVERLAPPED pointers. | 302 // |handler| will have valid OVERLAPPED pointers. |
| 324 static ULONG_PTR HandlerToKey(IOHandler* handler, bool has_valid_io_context); | 303 static ULONG_PTR HandlerToKey(IOHandler* handler, bool has_valid_io_context); |
| 325 | 304 |
| 326 // Converts a completion port key to an IOHandler pointer. | 305 // Converts a completion port key to an IOHandler pointer. |
| 327 static IOHandler* KeyToHandler(ULONG_PTR key, bool* has_valid_io_context); | 306 static IOHandler* KeyToHandler(ULONG_PTR key, bool* has_valid_io_context); |
| 328 | 307 |
| 329 // The completion port associated with this thread. | 308 // The completion port associated with this thread. |
| 330 win::ScopedHandle port_; | 309 win::ScopedHandle port_; |
| 331 // This list will be empty almost always. It stores IO completions that have | 310 // This list will be empty almost always. It stores IO completions that have |
| 332 // not been delivered yet because somebody was doing cleanup. | 311 // not been delivered yet because somebody was doing cleanup. |
| 333 std::list<IOItem> completed_io_; | 312 std::list<IOItem> completed_io_; |
| 334 | |
| 335 ObserverList<IOObserver> io_observers_; | |
| 336 }; | 313 }; |
| 337 | 314 |
| 338 } // namespace base | 315 } // namespace base |
| 339 | 316 |
| 340 #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ | 317 #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_ |
| OLD | NEW |