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