1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef BASE_WAITABLE_EVENT_WATCHER_H_ 6#define BASE_WAITABLE_EVENT_WATCHER_H_ 7 8#include "build/build_config.h" 9 10#if defined(OS_WIN) 11#include "base/object_watcher.h" 12#else 13#include "base/message_loop.h" 14#include "base/waitable_event.h" 15#endif 16 17namespace base { 18 19class Flag; 20class AsyncWaiter; 21class AsyncCallbackTask; 22class WaitableEvent; 23 24// ----------------------------------------------------------------------------- 25// This class provides a way to wait on a WaitableEvent asynchronously. 26// 27// Each instance of this object can be waiting on a single WaitableEvent. When 28// the waitable event is signaled, a callback is made in the thread of a given 29// MessageLoop. This callback can be deleted by deleting the waiter. 30// 31// Typical usage: 32// 33// class MyClass : public base::WaitableEventWatcher::Delegate { 34// public: 35// void DoStuffWhenSignaled(WaitableEvent *waitable_event) { 36// watcher_.StartWatching(waitable_event, this); 37// } 38// virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) { 39// // OK, time to do stuff! 40// } 41// private: 42// base::WaitableEventWatcher watcher_; 43// }; 44// 45// In the above example, MyClass wants to "do stuff" when waitable_event 46// becomes signaled. WaitableEventWatcher makes this task easy. When MyClass 47// goes out of scope, the watcher_ will be destroyed, and there is no need to 48// worry about OnWaitableEventSignaled being called on a deleted MyClass 49// pointer. 50// 51// BEWARE: With automatically reset WaitableEvents, a signal may be lost if it 52// occurs just before a WaitableEventWatcher is deleted. There is currently no 53// safe way to stop watching an automatic reset WaitableEvent without possibly 54// missing a signal. 55// 56// NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on 57// it with a Watcher. It will act as if the event was never signaled. 58// ----------------------------------------------------------------------------- 59 60class WaitableEventWatcher 61#if defined(OS_POSIX) 62 : public MessageLoop::DestructionObserver 63#endif 64{ 65 public: 66 67 WaitableEventWatcher(); 68 ~WaitableEventWatcher(); 69 70 class Delegate { 71 public: 72 virtual ~Delegate() { } 73 74 // ------------------------------------------------------------------------- 75 // This is called on the MessageLoop thread when WaitableEvent has been 76 // signaled. 77 // 78 // Note: the event may not be signaled by the time that this function is 79 // called. This indicates only that it has been signaled at some point in 80 // the past. 81 // ------------------------------------------------------------------------- 82 virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) = 0; 83 }; 84 85 // --------------------------------------------------------------------------- 86 // When @event is signaled, the given delegate is called on the thread of the 87 // current message loop when StartWatching is called. The delegate is not 88 // deleted. 89 // --------------------------------------------------------------------------- 90 bool StartWatching(WaitableEvent* event, Delegate* delegate); 91 92 // --------------------------------------------------------------------------- 93 // Cancel the current watch. Must be called from the same thread which 94 // started the watch. 95 // 96 // Does nothing if no event is being watched, nor if the watch has completed. 97 // The delegate will *not* be called for the current watch after this 98 // function returns. Since the delegate runs on the same thread as this 99 // function, it cannot be called during this function either. 100 // --------------------------------------------------------------------------- 101 void StopWatching(); 102 103 // --------------------------------------------------------------------------- 104 // Return the currently watched event, or NULL if no object is currently being 105 // watched. 106 // --------------------------------------------------------------------------- 107 WaitableEvent* GetWatchedEvent(); 108 109 // --------------------------------------------------------------------------- 110 // Return the delegate, or NULL if there is no delegate. 111 // --------------------------------------------------------------------------- 112 Delegate* delegate() { 113 return delegate_; 114 } 115 116 private: 117 WaitableEvent* event_; 118 119#if defined(OS_WIN) 120 // --------------------------------------------------------------------------- 121 // The helper class exists because, if WaitableEventWatcher were to inherit 122 // from ObjectWatcher::Delegate, then it couldn't also have an inner class 123 // called Delegate (at least on Windows). Thus this object exists to proxy 124 // the callback function 125 // --------------------------------------------------------------------------- 126 class ObjectWatcherHelper : public ObjectWatcher::Delegate { 127 public: 128 ObjectWatcherHelper(WaitableEventWatcher* watcher); 129 130 // ------------------------------------------------------------------------- 131 // Implementation of ObjectWatcher::Delegate 132 // ------------------------------------------------------------------------- 133 void OnObjectSignaled(HANDLE h); 134 135 private: 136 WaitableEventWatcher *const watcher_; 137 }; 138 139 void OnObjectSignaled(); 140 141 ObjectWatcherHelper helper_; 142 ObjectWatcher watcher_; 143#else 144 // --------------------------------------------------------------------------- 145 // Implementation of MessageLoop::DestructionObserver 146 // --------------------------------------------------------------------------- 147 void WillDestroyCurrentMessageLoop(); 148 149 MessageLoop* message_loop_; 150 scoped_refptr<Flag> cancel_flag_; 151 AsyncWaiter* waiter_; 152 AsyncCallbackTask* callback_task_; 153 scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; 154#endif 155 156 Delegate* delegate_; 157}; 158 159} // namespace base 160 161#endif // BASE_WAITABLE_EVENT_WATCHER_H_ 162