xref: /aosp_15_r20/external/libchrome/base/synchronization/waitable_event.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
12*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
15*635a8641SAndroid Build Coastguard Worker #include "base/win/scoped_handle.h"
16*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX)
17*635a8641SAndroid Build Coastguard Worker #include <mach/mach.h>
18*635a8641SAndroid Build Coastguard Worker 
19*635a8641SAndroid Build Coastguard Worker #include <list>
20*635a8641SAndroid Build Coastguard Worker #include <memory>
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker #include "base/callback_forward.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/mac/scoped_mach_port.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
26*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
27*635a8641SAndroid Build Coastguard Worker #include <list>
28*635a8641SAndroid Build Coastguard Worker #include <utility>
29*635a8641SAndroid Build Coastguard Worker 
30*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
32*635a8641SAndroid Build Coastguard Worker #endif
33*635a8641SAndroid Build Coastguard Worker 
34*635a8641SAndroid Build Coastguard Worker namespace base {
35*635a8641SAndroid Build Coastguard Worker 
36*635a8641SAndroid Build Coastguard Worker class TimeDelta;
37*635a8641SAndroid Build Coastguard Worker class TimeTicks;
38*635a8641SAndroid Build Coastguard Worker 
39*635a8641SAndroid Build Coastguard Worker // A WaitableEvent can be a useful thread synchronization tool when you want to
40*635a8641SAndroid Build Coastguard Worker // allow one thread to wait for another thread to finish some work. For
41*635a8641SAndroid Build Coastguard Worker // non-Windows systems, this can only be used from within a single address
42*635a8641SAndroid Build Coastguard Worker // space.
43*635a8641SAndroid Build Coastguard Worker //
44*635a8641SAndroid Build Coastguard Worker // Use a WaitableEvent when you would otherwise use a Lock+ConditionVariable to
45*635a8641SAndroid Build Coastguard Worker // protect a simple boolean value.  However, if you find yourself using a
46*635a8641SAndroid Build Coastguard Worker // WaitableEvent in conjunction with a Lock to wait for a more complex state
47*635a8641SAndroid Build Coastguard Worker // change (e.g., for an item to be added to a queue), then you should probably
48*635a8641SAndroid Build Coastguard Worker // be using a ConditionVariable instead of a WaitableEvent.
49*635a8641SAndroid Build Coastguard Worker //
50*635a8641SAndroid Build Coastguard Worker // NOTE: On Windows, this class provides a subset of the functionality afforded
51*635a8641SAndroid Build Coastguard Worker // by a Windows event object.  This is intentional.  If you are writing Windows
52*635a8641SAndroid Build Coastguard Worker // specific code and you need other features of a Windows event, then you might
53*635a8641SAndroid Build Coastguard Worker // be better off just using an Windows event directly.
54*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT WaitableEvent {
55*635a8641SAndroid Build Coastguard Worker  public:
56*635a8641SAndroid Build Coastguard Worker   // Indicates whether a WaitableEvent should automatically reset the event
57*635a8641SAndroid Build Coastguard Worker   // state after a single waiting thread has been released or remain signaled
58*635a8641SAndroid Build Coastguard Worker   // until Reset() is manually invoked.
59*635a8641SAndroid Build Coastguard Worker   enum class ResetPolicy { MANUAL, AUTOMATIC };
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker   // Indicates whether a new WaitableEvent should start in a signaled state or
62*635a8641SAndroid Build Coastguard Worker   // not.
63*635a8641SAndroid Build Coastguard Worker   enum class InitialState { SIGNALED, NOT_SIGNALED };
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker   // Constructs a WaitableEvent with policy and initial state as detailed in
66*635a8641SAndroid Build Coastguard Worker   // the above enums.
67*635a8641SAndroid Build Coastguard Worker   WaitableEvent(ResetPolicy reset_policy = ResetPolicy::MANUAL,
68*635a8641SAndroid Build Coastguard Worker                 InitialState initial_state = InitialState::NOT_SIGNALED);
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
71*635a8641SAndroid Build Coastguard Worker   // Create a WaitableEvent from an Event HANDLE which has already been
72*635a8641SAndroid Build Coastguard Worker   // created. This objects takes ownership of the HANDLE and will close it when
73*635a8641SAndroid Build Coastguard Worker   // deleted.
74*635a8641SAndroid Build Coastguard Worker   explicit WaitableEvent(win::ScopedHandle event_handle);
75*635a8641SAndroid Build Coastguard Worker #endif
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker   ~WaitableEvent();
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker   // Put the event in the un-signaled state.
80*635a8641SAndroid Build Coastguard Worker   void Reset();
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   // Put the event in the signaled state.  Causing any thread blocked on Wait
83*635a8641SAndroid Build Coastguard Worker   // to be woken up.
84*635a8641SAndroid Build Coastguard Worker   void Signal();
85*635a8641SAndroid Build Coastguard Worker 
86*635a8641SAndroid Build Coastguard Worker   // Returns true if the event is in the signaled state, else false.  If this
87*635a8641SAndroid Build Coastguard Worker   // is not a manual reset event, then this test will cause a reset.
88*635a8641SAndroid Build Coastguard Worker   bool IsSignaled();
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker   // Wait indefinitely for the event to be signaled. Wait's return "happens
91*635a8641SAndroid Build Coastguard Worker   // after" |Signal| has completed. This means that it's safe for a
92*635a8641SAndroid Build Coastguard Worker   // WaitableEvent to synchronise its own destruction, like this:
93*635a8641SAndroid Build Coastguard Worker   //
94*635a8641SAndroid Build Coastguard Worker   //   WaitableEvent *e = new WaitableEvent;
95*635a8641SAndroid Build Coastguard Worker   //   SendToOtherThread(e);
96*635a8641SAndroid Build Coastguard Worker   //   e->Wait();
97*635a8641SAndroid Build Coastguard Worker   //   delete e;
98*635a8641SAndroid Build Coastguard Worker   void Wait();
99*635a8641SAndroid Build Coastguard Worker 
100*635a8641SAndroid Build Coastguard Worker   // Wait up until wait_delta has passed for the event to be signaled.  Returns
101*635a8641SAndroid Build Coastguard Worker   // true if the event was signaled.
102*635a8641SAndroid Build Coastguard Worker   //
103*635a8641SAndroid Build Coastguard Worker   // TimedWait can synchronise its own destruction like |Wait|.
104*635a8641SAndroid Build Coastguard Worker   bool TimedWait(const TimeDelta& wait_delta);
105*635a8641SAndroid Build Coastguard Worker 
106*635a8641SAndroid Build Coastguard Worker   // Wait up until end_time deadline has passed for the event to be signaled.
107*635a8641SAndroid Build Coastguard Worker   // Return true if the event was signaled.
108*635a8641SAndroid Build Coastguard Worker   //
109*635a8641SAndroid Build Coastguard Worker   // TimedWaitUntil can synchronise its own destruction like |Wait|.
110*635a8641SAndroid Build Coastguard Worker   bool TimedWaitUntil(const TimeTicks& end_time);
111*635a8641SAndroid Build Coastguard Worker 
112*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
handle()113*635a8641SAndroid Build Coastguard Worker   HANDLE handle() const { return handle_.Get(); }
114*635a8641SAndroid Build Coastguard Worker #endif
115*635a8641SAndroid Build Coastguard Worker 
116*635a8641SAndroid Build Coastguard Worker   // Wait, synchronously, on multiple events.
117*635a8641SAndroid Build Coastguard Worker   //   waitables: an array of WaitableEvent pointers
118*635a8641SAndroid Build Coastguard Worker   //   count: the number of elements in @waitables
119*635a8641SAndroid Build Coastguard Worker   //
120*635a8641SAndroid Build Coastguard Worker   // returns: the index of a WaitableEvent which has been signaled.
121*635a8641SAndroid Build Coastguard Worker   //
122*635a8641SAndroid Build Coastguard Worker   // You MUST NOT delete any of the WaitableEvent objects while this wait is
123*635a8641SAndroid Build Coastguard Worker   // happening, however WaitMany's return "happens after" the |Signal| call
124*635a8641SAndroid Build Coastguard Worker   // that caused it has completed, like |Wait|.
125*635a8641SAndroid Build Coastguard Worker   //
126*635a8641SAndroid Build Coastguard Worker   // If more than one WaitableEvent is signaled to unblock WaitMany, the lowest
127*635a8641SAndroid Build Coastguard Worker   // index among them is returned.
128*635a8641SAndroid Build Coastguard Worker   static size_t WaitMany(WaitableEvent** waitables, size_t count);
129*635a8641SAndroid Build Coastguard Worker 
130*635a8641SAndroid Build Coastguard Worker   // For asynchronous waiting, see WaitableEventWatcher
131*635a8641SAndroid Build Coastguard Worker 
132*635a8641SAndroid Build Coastguard Worker   // This is a private helper class. It's here because it's used by friends of
133*635a8641SAndroid Build Coastguard Worker   // this class (such as WaitableEventWatcher) to be able to enqueue elements
134*635a8641SAndroid Build Coastguard Worker   // of the wait-list
135*635a8641SAndroid Build Coastguard Worker   class Waiter {
136*635a8641SAndroid Build Coastguard Worker    public:
137*635a8641SAndroid Build Coastguard Worker     // Signal the waiter to wake up.
138*635a8641SAndroid Build Coastguard Worker     //
139*635a8641SAndroid Build Coastguard Worker     // Consider the case of a Waiter which is in multiple WaitableEvent's
140*635a8641SAndroid Build Coastguard Worker     // wait-lists. Each WaitableEvent is automatic-reset and two of them are
141*635a8641SAndroid Build Coastguard Worker     // signaled at the same time. Now, each will wake only the first waiter in
142*635a8641SAndroid Build Coastguard Worker     // the wake-list before resetting. However, if those two waiters happen to
143*635a8641SAndroid Build Coastguard Worker     // be the same object (as can happen if another thread didn't have a chance
144*635a8641SAndroid Build Coastguard Worker     // to dequeue the waiter from the other wait-list in time), two auto-resets
145*635a8641SAndroid Build Coastguard Worker     // will have happened, but only one waiter has been signaled!
146*635a8641SAndroid Build Coastguard Worker     //
147*635a8641SAndroid Build Coastguard Worker     // Because of this, a Waiter may "reject" a wake by returning false. In
148*635a8641SAndroid Build Coastguard Worker     // this case, the auto-reset WaitableEvent shouldn't act as if anything has
149*635a8641SAndroid Build Coastguard Worker     // been notified.
150*635a8641SAndroid Build Coastguard Worker     virtual bool Fire(WaitableEvent* signaling_event) = 0;
151*635a8641SAndroid Build Coastguard Worker 
152*635a8641SAndroid Build Coastguard Worker     // Waiters may implement this in order to provide an extra condition for
153*635a8641SAndroid Build Coastguard Worker     // two Waiters to be considered equal. In WaitableEvent::Dequeue, if the
154*635a8641SAndroid Build Coastguard Worker     // pointers match then this function is called as a final check. See the
155*635a8641SAndroid Build Coastguard Worker     // comments in ~Handle for why.
156*635a8641SAndroid Build Coastguard Worker     virtual bool Compare(void* tag) = 0;
157*635a8641SAndroid Build Coastguard Worker 
158*635a8641SAndroid Build Coastguard Worker    protected:
159*635a8641SAndroid Build Coastguard Worker     virtual ~Waiter() = default;
160*635a8641SAndroid Build Coastguard Worker   };
161*635a8641SAndroid Build Coastguard Worker 
162*635a8641SAndroid Build Coastguard Worker  private:
163*635a8641SAndroid Build Coastguard Worker   friend class WaitableEventWatcher;
164*635a8641SAndroid Build Coastguard Worker 
165*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
166*635a8641SAndroid Build Coastguard Worker   win::ScopedHandle handle_;
167*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX)
168*635a8641SAndroid Build Coastguard Worker   // Prior to macOS 10.12, a TYPE_MACH_RECV dispatch source may not be invoked
169*635a8641SAndroid Build Coastguard Worker   // immediately. If a WaitableEventWatcher is used on a manual-reset event,
170*635a8641SAndroid Build Coastguard Worker   // and another thread that is Wait()ing on the event calls Reset()
171*635a8641SAndroid Build Coastguard Worker   // immediately after waking up, the watcher may not receive the callback.
172*635a8641SAndroid Build Coastguard Worker   // On macOS 10.12 and higher, dispatch delivery is reliable. But for OSes
173*635a8641SAndroid Build Coastguard Worker   // prior, a lock-protected list of callbacks is used for manual-reset event
174*635a8641SAndroid Build Coastguard Worker   // watchers. Automatic-reset events are not prone to this issue, since the
175*635a8641SAndroid Build Coastguard Worker   // first thread to wake will claim the event.
176*635a8641SAndroid Build Coastguard Worker   static bool UseSlowWatchList(ResetPolicy policy);
177*635a8641SAndroid Build Coastguard Worker 
178*635a8641SAndroid Build Coastguard Worker   // Peeks the message queue named by |port| and returns true if a message
179*635a8641SAndroid Build Coastguard Worker   // is present and false if not. If |dequeue| is true, the messsage will be
180*635a8641SAndroid Build Coastguard Worker   // drained from the queue. If |dequeue| is false, the queue will only be
181*635a8641SAndroid Build Coastguard Worker   // peeked. |port| must be a receive right.
182*635a8641SAndroid Build Coastguard Worker   static bool PeekPort(mach_port_t port, bool dequeue);
183*635a8641SAndroid Build Coastguard Worker 
184*635a8641SAndroid Build Coastguard Worker   // The Mach receive right is waited on by both WaitableEvent and
185*635a8641SAndroid Build Coastguard Worker   // WaitableEventWatcher. It is valid to signal and then delete an event, and
186*635a8641SAndroid Build Coastguard Worker   // a watcher should still be notified. If the right were to be destroyed
187*635a8641SAndroid Build Coastguard Worker   // immediately, the watcher would not receive the signal. Because Mach
188*635a8641SAndroid Build Coastguard Worker   // receive rights cannot have a user refcount greater than one, the right
189*635a8641SAndroid Build Coastguard Worker   // must be reference-counted manually.
190*635a8641SAndroid Build Coastguard Worker   class ReceiveRight : public RefCountedThreadSafe<ReceiveRight> {
191*635a8641SAndroid Build Coastguard Worker    public:
192*635a8641SAndroid Build Coastguard Worker     ReceiveRight(mach_port_t name, bool create_slow_watch_list);
193*635a8641SAndroid Build Coastguard Worker 
Name()194*635a8641SAndroid Build Coastguard Worker     mach_port_t Name() const { return right_.get(); };
195*635a8641SAndroid Build Coastguard Worker 
196*635a8641SAndroid Build Coastguard Worker     // This structure is used iff UseSlowWatchList() is true. See the comment
197*635a8641SAndroid Build Coastguard Worker     // in Signal() for details.
198*635a8641SAndroid Build Coastguard Worker     struct WatchList {
199*635a8641SAndroid Build Coastguard Worker       WatchList();
200*635a8641SAndroid Build Coastguard Worker       ~WatchList();
201*635a8641SAndroid Build Coastguard Worker 
202*635a8641SAndroid Build Coastguard Worker       // The lock protects a list of closures to be run when the event is
203*635a8641SAndroid Build Coastguard Worker       // Signal()ed. The closures are invoked on the signaling thread, so they
204*635a8641SAndroid Build Coastguard Worker       // must be safe to be called from any thread.
205*635a8641SAndroid Build Coastguard Worker       Lock lock;
206*635a8641SAndroid Build Coastguard Worker       std::list<OnceClosure> list;
207*635a8641SAndroid Build Coastguard Worker     };
208*635a8641SAndroid Build Coastguard Worker 
SlowWatchList()209*635a8641SAndroid Build Coastguard Worker     WatchList* SlowWatchList() const { return slow_watch_list_.get(); }
210*635a8641SAndroid Build Coastguard Worker 
211*635a8641SAndroid Build Coastguard Worker    private:
212*635a8641SAndroid Build Coastguard Worker     friend class RefCountedThreadSafe<ReceiveRight>;
213*635a8641SAndroid Build Coastguard Worker     ~ReceiveRight();
214*635a8641SAndroid Build Coastguard Worker 
215*635a8641SAndroid Build Coastguard Worker     mac::ScopedMachReceiveRight right_;
216*635a8641SAndroid Build Coastguard Worker 
217*635a8641SAndroid Build Coastguard Worker     // This is allocated iff UseSlowWatchList() is true. It is created on the
218*635a8641SAndroid Build Coastguard Worker     // heap to avoid performing initialization when not using the slow path.
219*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<WatchList> slow_watch_list_;
220*635a8641SAndroid Build Coastguard Worker 
221*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ReceiveRight);
222*635a8641SAndroid Build Coastguard Worker   };
223*635a8641SAndroid Build Coastguard Worker 
224*635a8641SAndroid Build Coastguard Worker   const ResetPolicy policy_;
225*635a8641SAndroid Build Coastguard Worker 
226*635a8641SAndroid Build Coastguard Worker   // The receive right for the event.
227*635a8641SAndroid Build Coastguard Worker   scoped_refptr<ReceiveRight> receive_right_;
228*635a8641SAndroid Build Coastguard Worker 
229*635a8641SAndroid Build Coastguard Worker   // The send right used to signal the event. This can be disposed of with
230*635a8641SAndroid Build Coastguard Worker   // the event, unlike the receive right, since a deleted event cannot be
231*635a8641SAndroid Build Coastguard Worker   // signaled.
232*635a8641SAndroid Build Coastguard Worker   mac::ScopedMachSendRight send_right_;
233*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
234*635a8641SAndroid Build Coastguard Worker   // On Windows, you must not close a HANDLE which is currently being waited on.
235*635a8641SAndroid Build Coastguard Worker   // The MSDN documentation says that the resulting behaviour is 'undefined'.
236*635a8641SAndroid Build Coastguard Worker   // To solve that issue each WaitableEventWatcher duplicates the given event
237*635a8641SAndroid Build Coastguard Worker   // handle.
238*635a8641SAndroid Build Coastguard Worker 
239*635a8641SAndroid Build Coastguard Worker   // However, if we were to include the following members
240*635a8641SAndroid Build Coastguard Worker   // directly then, on POSIX, one couldn't use WaitableEventWatcher to watch an
241*635a8641SAndroid Build Coastguard Worker   // event which gets deleted. This mismatch has bitten us several times now,
242*635a8641SAndroid Build Coastguard Worker   // so we have a kernel of the WaitableEvent, which is reference counted.
243*635a8641SAndroid Build Coastguard Worker   // WaitableEventWatchers may then take a reference and thus match the Windows
244*635a8641SAndroid Build Coastguard Worker   // behaviour.
245*635a8641SAndroid Build Coastguard Worker   struct WaitableEventKernel :
246*635a8641SAndroid Build Coastguard Worker       public RefCountedThreadSafe<WaitableEventKernel> {
247*635a8641SAndroid Build Coastguard Worker    public:
248*635a8641SAndroid Build Coastguard Worker     WaitableEventKernel(ResetPolicy reset_policy, InitialState initial_state);
249*635a8641SAndroid Build Coastguard Worker 
250*635a8641SAndroid Build Coastguard Worker     bool Dequeue(Waiter* waiter, void* tag);
251*635a8641SAndroid Build Coastguard Worker 
252*635a8641SAndroid Build Coastguard Worker     base::Lock lock_;
253*635a8641SAndroid Build Coastguard Worker     const bool manual_reset_;
254*635a8641SAndroid Build Coastguard Worker     bool signaled_;
255*635a8641SAndroid Build Coastguard Worker     std::list<Waiter*> waiters_;
256*635a8641SAndroid Build Coastguard Worker 
257*635a8641SAndroid Build Coastguard Worker    private:
258*635a8641SAndroid Build Coastguard Worker     friend class RefCountedThreadSafe<WaitableEventKernel>;
259*635a8641SAndroid Build Coastguard Worker     ~WaitableEventKernel();
260*635a8641SAndroid Build Coastguard Worker   };
261*635a8641SAndroid Build Coastguard Worker 
262*635a8641SAndroid Build Coastguard Worker   typedef std::pair<WaitableEvent*, size_t> WaiterAndIndex;
263*635a8641SAndroid Build Coastguard Worker 
264*635a8641SAndroid Build Coastguard Worker   // When dealing with arrays of WaitableEvent*, we want to sort by the address
265*635a8641SAndroid Build Coastguard Worker   // of the WaitableEvent in order to have a globally consistent locking order.
266*635a8641SAndroid Build Coastguard Worker   // In that case we keep them, in sorted order, in an array of pairs where the
267*635a8641SAndroid Build Coastguard Worker   // second element is the index of the WaitableEvent in the original,
268*635a8641SAndroid Build Coastguard Worker   // unsorted, array.
269*635a8641SAndroid Build Coastguard Worker   static size_t EnqueueMany(WaiterAndIndex* waitables,
270*635a8641SAndroid Build Coastguard Worker                             size_t count, Waiter* waiter);
271*635a8641SAndroid Build Coastguard Worker 
272*635a8641SAndroid Build Coastguard Worker   bool SignalAll();
273*635a8641SAndroid Build Coastguard Worker   bool SignalOne();
274*635a8641SAndroid Build Coastguard Worker   void Enqueue(Waiter* waiter);
275*635a8641SAndroid Build Coastguard Worker 
276*635a8641SAndroid Build Coastguard Worker   scoped_refptr<WaitableEventKernel> kernel_;
277*635a8641SAndroid Build Coastguard Worker #endif
278*635a8641SAndroid Build Coastguard Worker 
279*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(WaitableEvent);
280*635a8641SAndroid Build Coastguard Worker };
281*635a8641SAndroid Build Coastguard Worker 
282*635a8641SAndroid Build Coastguard Worker }  // namespace base
283*635a8641SAndroid Build Coastguard Worker 
284*635a8641SAndroid Build Coastguard Worker #endif  // BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_
285