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