|
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 |
|
17 namespace base { |
|
18 |
|
19 class Flag; |
|
20 class AsyncWaiter; |
|
21 class AsyncCallbackTask; |
|
22 class 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 |
|
60 class 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 private: |
|
110 WaitableEvent* event_; |
|
111 |
|
112 #if defined(OS_WIN) |
|
113 // --------------------------------------------------------------------------- |
|
114 // The helper class exists because, if WaitableEventWatcher were to inherit |
|
115 // from ObjectWatcher::Delegate, then it couldn't also have an inner class |
|
116 // called Delegate (at least on Windows). Thus this object exists to proxy |
|
117 // the callback function |
|
118 // --------------------------------------------------------------------------- |
|
119 class ObjectWatcherHelper : public ObjectWatcher::Delegate { |
|
120 public: |
|
121 ObjectWatcherHelper(WaitableEventWatcher* watcher); |
|
122 |
|
123 // ------------------------------------------------------------------------- |
|
124 // Implementation of ObjectWatcher::Delegate |
|
125 // ------------------------------------------------------------------------- |
|
126 void OnObjectSignaled(HANDLE h); |
|
127 |
|
128 private: |
|
129 WaitableEventWatcher *const watcher_; |
|
130 }; |
|
131 |
|
132 void OnObjectSignaled(); |
|
133 |
|
134 Delegate* delegate_; |
|
135 ObjectWatcherHelper helper_; |
|
136 ObjectWatcher watcher_; |
|
137 #else |
|
138 // --------------------------------------------------------------------------- |
|
139 // Implementation of MessageLoop::DestructionObserver |
|
140 // --------------------------------------------------------------------------- |
|
141 void WillDestroyCurrentMessageLoop(); |
|
142 |
|
143 MessageLoop* message_loop_; |
|
144 scoped_refptr<Flag> cancel_flag_; |
|
145 AsyncWaiter* waiter_; |
|
146 AsyncCallbackTask* callback_task_; |
|
147 scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; |
|
148 #endif |
|
149 }; |
|
150 |
|
151 } // namespace base |
|
152 |
|
153 #endif // BASE_WAITABLE_EVENT_WATCHER_H_ |