1 // Copyright (c) 2011 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.
5 #ifndef BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_
6 #define BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_
9 #include "build/build_config.h"
12 #include "base/win/object_watcher.h"
14 #include "base/message_loop.h"
15 #include "base/synchronization/waitable_event.h"
18 #include "base/base_export.h"
24 class AsyncCallbackTask
;
27 // -----------------------------------------------------------------------------
28 // This class provides a way to wait on a WaitableEvent asynchronously.
30 // Each instance of this object can be waiting on a single WaitableEvent. When
31 // the waitable event is signaled, a callback is made in the thread of a given
32 // MessageLoop. This callback can be deleted by deleting the waiter.
36 // class MyClass : public base::WaitableEventWatcher::Delegate {
38 // void DoStuffWhenSignaled(WaitableEvent *waitable_event) {
39 // watcher_.StartWatching(waitable_event, this);
41 // virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) {
42 // // OK, time to do stuff!
45 // base::WaitableEventWatcher watcher_;
48 // In the above example, MyClass wants to "do stuff" when waitable_event
49 // becomes signaled. WaitableEventWatcher makes this task easy. When MyClass
50 // goes out of scope, the watcher_ will be destroyed, and there is no need to
51 // worry about OnWaitableEventSignaled being called on a deleted MyClass
54 // BEWARE: With automatically reset WaitableEvents, a signal may be lost if it
55 // occurs just before a WaitableEventWatcher is deleted. There is currently no
56 // safe way to stop watching an automatic reset WaitableEvent without possibly
59 // NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on
60 // it with a Watcher. It will act as if the event was never signaled.
61 // -----------------------------------------------------------------------------
63 class BASE_EXPORT WaitableEventWatcher
65 : public MessageLoop::DestructionObserver
70 WaitableEventWatcher();
71 virtual ~WaitableEventWatcher();
73 class BASE_EXPORT Delegate
{
75 virtual ~Delegate() { }
77 // -------------------------------------------------------------------------
78 // This is called on the MessageLoop thread when WaitableEvent has been
81 // Note: the event may not be signaled by the time that this function is
82 // called. This indicates only that it has been signaled at some point in
84 // -------------------------------------------------------------------------
85 virtual void OnWaitableEventSignaled(WaitableEvent
* waitable_event
) = 0;
88 // ---------------------------------------------------------------------------
89 // When @event is signaled, the given delegate is called on the thread of the
90 // current message loop when StartWatching is called. The delegate is not
92 // ---------------------------------------------------------------------------
93 bool StartWatching(WaitableEvent
* event
, Delegate
* delegate
);
95 // ---------------------------------------------------------------------------
96 // Cancel the current watch. Must be called from the same thread which
99 // Does nothing if no event is being watched, nor if the watch has completed.
100 // The delegate will *not* be called for the current watch after this
101 // function returns. Since the delegate runs on the same thread as this
102 // function, it cannot be called during this function either.
103 // ---------------------------------------------------------------------------
106 // ---------------------------------------------------------------------------
107 // Return the currently watched event, or NULL if no object is currently being
109 // ---------------------------------------------------------------------------
110 WaitableEvent
* GetWatchedEvent();
112 // ---------------------------------------------------------------------------
113 // Return the delegate, or NULL if there is no delegate.
114 // ---------------------------------------------------------------------------
115 Delegate
* delegate() {
121 // ---------------------------------------------------------------------------
122 // The helper class exists because, if WaitableEventWatcher were to inherit
123 // from ObjectWatcher::Delegate, then it couldn't also have an inner class
124 // called Delegate (at least on Windows). Thus this object exists to proxy
125 // the callback function
126 // ---------------------------------------------------------------------------
127 class ObjectWatcherHelper
: public win::ObjectWatcher::Delegate
{
129 ObjectWatcherHelper(WaitableEventWatcher
* watcher
);
131 // -------------------------------------------------------------------------
132 // Implementation of ObjectWatcher::Delegate
133 // -------------------------------------------------------------------------
134 void OnObjectSignaled(HANDLE h
);
137 WaitableEventWatcher
*const watcher_
;
140 void OnObjectSignaled();
142 ObjectWatcherHelper helper_
;
143 win::ObjectWatcher watcher_
;
145 // ---------------------------------------------------------------------------
146 // Implementation of MessageLoop::DestructionObserver
147 // ---------------------------------------------------------------------------
148 virtual void WillDestroyCurrentMessageLoop();
150 MessageLoop
* message_loop_
;
151 scoped_refptr
<Flag
> cancel_flag_
;
152 AsyncWaiter
* waiter_
;
153 AsyncCallbackTask
* callback_task_
;
154 scoped_refptr
<WaitableEvent::WaitableEventKernel
> kernel_
;
157 WaitableEvent
* event_
;
164 #endif // BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_