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