Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Side by Side Diff: base/waitable_event.h

Issue 16554: WaitableEvent (Closed)
Patch Set: Addresssing darin's comments (round 2) Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/build/base.vcproj ('k') | base/waitable_event_generic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 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 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_WAITABLE_EVENT_H_ 5 #ifndef BASE_WAITABLE_EVENT_H_
6 #define BASE_WAITABLE_EVENT_H_ 6 #define BASE_WAITABLE_EVENT_H_
7 7
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 9
10 #if defined(OS_WIN) 10 #if defined(OS_WIN)
11 typedef void* HANDLE; 11 #include <windows.h>
12 #else 12 #endif
13
14 #if defined(OS_POSIX)
15 #include <list>
16 #include <utility>
13 #include "base/condition_variable.h" 17 #include "base/condition_variable.h"
14 #include "base/lock.h" 18 #include "base/lock.h"
19 #include "base/ref_counted.h"
15 #endif 20 #endif
16 21
22 #include "base/message_loop.h"
23
17 namespace base { 24 namespace base {
18 25
19 class TimeDelta; 26 class TimeDelta;
20 27
21 // A WaitableEvent can be a useful thread synchronization tool when you want to 28 // A WaitableEvent can be a useful thread synchronization tool when you want to
22 // allow one thread to wait for another thread to finish some work. 29 // allow one thread to wait for another thread to finish some work. For
30 // non-Windows systems, this can only be used from within a single address
31 // space.
23 // 32 //
24 // Use a WaitableEvent when you would otherwise use a Lock+ConditionVariable to 33 // Use a WaitableEvent when you would otherwise use a Lock+ConditionVariable to
25 // protect a simple boolean value. However, if you find yourself using a 34 // protect a simple boolean value. However, if you find yourself using a
26 // WaitableEvent in conjunction with a Lock to wait for a more complex state 35 // WaitableEvent in conjunction with a Lock to wait for a more complex state
27 // change (e.g., for an item to be added to a queue), then you should probably 36 // change (e.g., for an item to be added to a queue), then you should probably
28 // be using a ConditionVariable instead of a WaitableEvent. 37 // be using a ConditionVariable instead of a WaitableEvent.
29 // 38 //
30 // NOTE: On Windows, this class provides a subset of the functionality afforded 39 // NOTE: On Windows, this class provides a subset of the functionality afforded
31 // by a Windows event object. This is intentional. If you are writing Windows 40 // by a Windows event object. This is intentional. If you are writing Windows
32 // specific code and you need other features of a Windows event, then you might 41 // specific code and you need other features of a Windows event, then you might
33 // be better off just using an Windows event directly. 42 // be better off just using an Windows event directly.
34 //
35 class WaitableEvent { 43 class WaitableEvent {
36 public: 44 public:
37 // If manual_reset is true, then to set the event state to non-signaled, a 45 // If manual_reset is true, then to set the event state to non-signaled, a
38 // consumer must call the Reset method. If this parameter is false, then the 46 // consumer must call the Reset method. If this parameter is false, then the
39 // system automatically resets the event state to non-signaled after a single 47 // system automatically resets the event state to non-signaled after a single
40 // waiting thread has been released. 48 // waiting thread has been released.
41 WaitableEvent(bool manual_reset, bool initially_signaled); 49 WaitableEvent(bool manual_reset, bool initially_signaled);
42 50
51 #if defined(OS_WIN)
52 // Create a WaitableEvent from an Event HANDLE which has already been
53 // created. This objects takes ownership of the HANDLE and will close it when
54 // deleted.
55 explicit WaitableEvent(HANDLE event_handle);
56 #endif
57
43 // WARNING: Destroying a WaitableEvent while threads are waiting on it is not 58 // WARNING: Destroying a WaitableEvent while threads are waiting on it is not
44 // supported. Doing so will cause crashes or other instability. 59 // supported. Doing so will cause crashes or other instability.
45 ~WaitableEvent(); 60 ~WaitableEvent();
46 61
47 // Put the event in the un-signaled state. 62 // Put the event in the un-signaled state.
48 void Reset(); 63 void Reset();
49 64
50 // Put the event in the signaled state. Causing any thread blocked on Wait 65 // Put the event in the signaled state. Causing any thread blocked on Wait
51 // to be woken up. 66 // to be woken up.
52 void Signal(); 67 void Signal();
53 68
54 // Returns true if the event is in the signaled state, else false. If this 69 // Returns true if the event is in the signaled state, else false. If this
55 // is not a manual reset event, then this test will cause a reset. 70 // is not a manual reset event, then this test will cause a reset.
56 bool IsSignaled(); 71 bool IsSignaled();
57 72
58 // Wait indefinitely for the event to be signaled. Returns true if the event 73 // Wait indefinitely for the event to be signaled. Returns true if the event
59 // was signaled, else false is returned to indicate that waiting failed. 74 // was signaled, else false is returned to indicate that waiting failed.
60 bool Wait(); 75 bool Wait();
61 76
62 // Wait up until max_time has passed for the event to be signaled. Returns 77 // Wait up until max_time has passed for the event to be signaled. Returns
63 // true if the event was signaled. If this method returns false, then it 78 // true if the event was signaled. If this method returns false, then it
64 // does not necessarily mean that max_time was exceeded. 79 // does not necessarily mean that max_time was exceeded.
65 bool TimedWait(const TimeDelta& max_time); 80 bool TimedWait(const TimeDelta& max_time);
66 81
82 #if defined(OS_WIN)
83 HANDLE handle() const { return handle_; }
84 #endif
85
86 // Wait, synchronously, on multiple events.
87 // waitables: an array of WaitableEvent pointers
88 // count: the number of elements in @waitables
89 //
90 // returns: the index of a WaitableEvent which has been signaled.
91 static size_t WaitMany(WaitableEvent** waitables, size_t count);
92
93 // For asynchronous waiting, see WaitableEventWatcher
94
95 // This is a private helper class. It's here because it's used by friends of
96 // this class (such as WaitableEventWatcher) to be able to enqueue elements
97 // of the wait-list
98 class Waiter {
99 public:
100 // Signal the waiter to wake up.
101 //
102 // Consider the case of a Waiter which is in multiple WaitableEvent's
103 // wait-lists. Each WaitableEvent is automatic-reset and two of them are
104 // signaled at the same time. Now, each will wake only the first waiter in
105 // the wake-list before resetting. However, if those two waiters happen to
106 // be the same object (as can happen if another thread didn't have a chance
107 // to dequeue the waiter from the other wait-list in time), two auto-resets
108 // will have happened, but only one waiter has been signaled!
109 //
110 // Because of this, a Waiter may "reject" a wake by returning false. In
111 // this case, the auto-reset WaitableEvent shouldn't act as if anything has
112 // been notified.
113 virtual bool Fire(WaitableEvent* signaling_event) = 0;
114
115 // Waiters may implement this in order to provide an extra condition for
116 // two Waiters to be considered equal. In WaitableEvent::Dequeue, if the
117 // pointers match then this function is called as a final check. See the
118 // comments in ~Handle for why.
119 virtual bool Compare(void* tag) = 0;
120 };
121
67 private: 122 private:
123 friend class WaitableEventWatcher;
124
68 #if defined(OS_WIN) 125 #if defined(OS_WIN)
69 HANDLE event_; 126 HANDLE handle_;
70 #else 127 #else
71 Lock lock_; // Needs to be listed first so it will be constructed first. 128 bool SignalAll();
72 ConditionVariable cvar_; 129 bool SignalOne();
130 void Enqueue(Waiter* waiter);
131 bool Dequeue(Waiter* waiter, void* tag);
132
133 // When dealing with arrays of WaitableEvent*, we want to sort by the address
134 // of the WaitableEvent in order to have a globally consistent locking order.
135 // In that case we keep them, in sorted order, in an array of pairs where the
136 // second element is the index of the WaitableEvent in the original,
137 // unsorted, array.
138 typedef std::pair<WaitableEvent*, size_t> WaiterAndIndex;
139 static unsigned EnqueueMany(WaiterAndIndex* waitables,
140 size_t count, Waiter* waiter);
141
142 Lock lock_;
73 bool signaled_; 143 bool signaled_;
74 bool manual_reset_; 144 const bool manual_reset_;
145 std::list<Waiter*> waiters_;
75 #endif 146 #endif
76 147
77 DISALLOW_COPY_AND_ASSIGN(WaitableEvent); 148 DISALLOW_COPY_AND_ASSIGN(WaitableEvent);
78 }; 149 };
79 150
80 } // namespace base 151 } // namespace base
81 152
82 #endif // BASE_WAITABLE_EVENT_H_ 153 #endif // BASE_WAITABLE_EVENT_H_
OLDNEW
« no previous file with comments | « base/build/base.vcproj ('k') | base/waitable_event_generic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698