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_WATCHER_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 9*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 10*635a8641SAndroid Build Coastguard Worker #include "base/sequenced_task_runner.h" 11*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h" 12*635a8641SAndroid Build Coastguard Worker 13*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 14*635a8641SAndroid Build Coastguard Worker #include "base/win/object_watcher.h" 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 <dispatch/dispatch.h> 18*635a8641SAndroid Build Coastguard Worker 19*635a8641SAndroid Build Coastguard Worker #include "base/mac/scoped_dispatch_object.h" 20*635a8641SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h" 21*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h" 22*635a8641SAndroid Build Coastguard Worker #else 23*635a8641SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 24*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h" 25*635a8641SAndroid Build Coastguard Worker #endif 26*635a8641SAndroid Build Coastguard Worker 27*635a8641SAndroid Build Coastguard Worker #if !defined(OS_WIN) 28*635a8641SAndroid Build Coastguard Worker #include "base/callback.h" 29*635a8641SAndroid Build Coastguard Worker #endif 30*635a8641SAndroid Build Coastguard Worker 31*635a8641SAndroid Build Coastguard Worker namespace base { 32*635a8641SAndroid Build Coastguard Worker 33*635a8641SAndroid Build Coastguard Worker class Flag; 34*635a8641SAndroid Build Coastguard Worker class AsyncWaiter; 35*635a8641SAndroid Build Coastguard Worker class WaitableEvent; 36*635a8641SAndroid Build Coastguard Worker 37*635a8641SAndroid Build Coastguard Worker // This class provides a way to wait on a WaitableEvent asynchronously. 38*635a8641SAndroid Build Coastguard Worker // 39*635a8641SAndroid Build Coastguard Worker // Each instance of this object can be waiting on a single WaitableEvent. When 40*635a8641SAndroid Build Coastguard Worker // the waitable event is signaled, a callback is invoked on the sequence that 41*635a8641SAndroid Build Coastguard Worker // called StartWatching(). This callback can be deleted by deleting the waiter. 42*635a8641SAndroid Build Coastguard Worker // 43*635a8641SAndroid Build Coastguard Worker // Typical usage: 44*635a8641SAndroid Build Coastguard Worker // 45*635a8641SAndroid Build Coastguard Worker // class MyClass { 46*635a8641SAndroid Build Coastguard Worker // public: 47*635a8641SAndroid Build Coastguard Worker // void DoStuffWhenSignaled(WaitableEvent *waitable_event) { 48*635a8641SAndroid Build Coastguard Worker // watcher_.StartWatching(waitable_event, 49*635a8641SAndroid Build Coastguard Worker // base::BindOnce(&MyClass::OnWaitableEventSignaled, this); 50*635a8641SAndroid Build Coastguard Worker // } 51*635a8641SAndroid Build Coastguard Worker // private: 52*635a8641SAndroid Build Coastguard Worker // void OnWaitableEventSignaled(WaitableEvent* waitable_event) { 53*635a8641SAndroid Build Coastguard Worker // // OK, time to do stuff! 54*635a8641SAndroid Build Coastguard Worker // } 55*635a8641SAndroid Build Coastguard Worker // base::WaitableEventWatcher watcher_; 56*635a8641SAndroid Build Coastguard Worker // }; 57*635a8641SAndroid Build Coastguard Worker // 58*635a8641SAndroid Build Coastguard Worker // In the above example, MyClass wants to "do stuff" when waitable_event 59*635a8641SAndroid Build Coastguard Worker // becomes signaled. WaitableEventWatcher makes this task easy. When MyClass 60*635a8641SAndroid Build Coastguard Worker // goes out of scope, the watcher_ will be destroyed, and there is no need to 61*635a8641SAndroid Build Coastguard Worker // worry about OnWaitableEventSignaled being called on a deleted MyClass 62*635a8641SAndroid Build Coastguard Worker // pointer. 63*635a8641SAndroid Build Coastguard Worker // 64*635a8641SAndroid Build Coastguard Worker // BEWARE: With automatically reset WaitableEvents, a signal may be lost if it 65*635a8641SAndroid Build Coastguard Worker // occurs just before a WaitableEventWatcher is deleted. There is currently no 66*635a8641SAndroid Build Coastguard Worker // safe way to stop watching an automatic reset WaitableEvent without possibly 67*635a8641SAndroid Build Coastguard Worker // missing a signal. 68*635a8641SAndroid Build Coastguard Worker // 69*635a8641SAndroid Build Coastguard Worker // NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on 70*635a8641SAndroid Build Coastguard Worker // it with a Watcher. But pay attention: if the event was signaled and deleted 71*635a8641SAndroid Build Coastguard Worker // right after, the callback may be called with deleted WaitableEvent pointer. 72*635a8641SAndroid Build Coastguard Worker 73*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT WaitableEventWatcher 74*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 75*635a8641SAndroid Build Coastguard Worker : public win::ObjectWatcher::Delegate 76*635a8641SAndroid Build Coastguard Worker #endif 77*635a8641SAndroid Build Coastguard Worker { 78*635a8641SAndroid Build Coastguard Worker public: 79*635a8641SAndroid Build Coastguard Worker using EventCallback = OnceCallback<void(WaitableEvent*)>; 80*635a8641SAndroid Build Coastguard Worker 81*635a8641SAndroid Build Coastguard Worker WaitableEventWatcher(); 82*635a8641SAndroid Build Coastguard Worker 83*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 84*635a8641SAndroid Build Coastguard Worker ~WaitableEventWatcher() override; 85*635a8641SAndroid Build Coastguard Worker #else 86*635a8641SAndroid Build Coastguard Worker ~WaitableEventWatcher(); 87*635a8641SAndroid Build Coastguard Worker #endif 88*635a8641SAndroid Build Coastguard Worker 89*635a8641SAndroid Build Coastguard Worker // When |event| is signaled, |callback| is called on the sequence that called 90*635a8641SAndroid Build Coastguard Worker // StartWatching(). 91*635a8641SAndroid Build Coastguard Worker // |task_runner| is used for asynchronous executions of calling |callback|. 92*635a8641SAndroid Build Coastguard Worker bool StartWatching(WaitableEvent* event, 93*635a8641SAndroid Build Coastguard Worker EventCallback callback, 94*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner); 95*635a8641SAndroid Build Coastguard Worker 96*635a8641SAndroid Build Coastguard Worker // Cancel the current watch. Must be called from the same sequence which 97*635a8641SAndroid Build Coastguard Worker // started the watch. 98*635a8641SAndroid Build Coastguard Worker // 99*635a8641SAndroid Build Coastguard Worker // Does nothing if no event is being watched, nor if the watch has completed. 100*635a8641SAndroid Build Coastguard Worker // The callback will *not* be called for the current watch after this 101*635a8641SAndroid Build Coastguard Worker // function returns. Since the callback runs on the same sequence as this 102*635a8641SAndroid Build Coastguard Worker // function, it cannot be called during this function either. 103*635a8641SAndroid Build Coastguard Worker void StopWatching(); 104*635a8641SAndroid Build Coastguard Worker 105*635a8641SAndroid Build Coastguard Worker private: 106*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 107*635a8641SAndroid Build Coastguard Worker void OnObjectSignaled(HANDLE h) override; 108*635a8641SAndroid Build Coastguard Worker 109*635a8641SAndroid Build Coastguard Worker // Duplicated handle of the event passed to StartWatching(). 110*635a8641SAndroid Build Coastguard Worker win::ScopedHandle duplicated_event_handle_; 111*635a8641SAndroid Build Coastguard Worker 112*635a8641SAndroid Build Coastguard Worker // A watcher for |duplicated_event_handle_|. The handle MUST outlive 113*635a8641SAndroid Build Coastguard Worker // |watcher_|. 114*635a8641SAndroid Build Coastguard Worker win::ObjectWatcher watcher_; 115*635a8641SAndroid Build Coastguard Worker 116*635a8641SAndroid Build Coastguard Worker EventCallback callback_; 117*635a8641SAndroid Build Coastguard Worker WaitableEvent* event_ = nullptr; 118*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) 119*635a8641SAndroid Build Coastguard Worker // Invokes the callback and resets the source. Must be called on the task 120*635a8641SAndroid Build Coastguard Worker // runner on which StartWatching() was called. 121*635a8641SAndroid Build Coastguard Worker void InvokeCallback(); 122*635a8641SAndroid Build Coastguard Worker 123*635a8641SAndroid Build Coastguard Worker // Closure bound to the event being watched. This will be is_null() if 124*635a8641SAndroid Build Coastguard Worker // nothing is being watched. 125*635a8641SAndroid Build Coastguard Worker OnceClosure callback_; 126*635a8641SAndroid Build Coastguard Worker 127*635a8641SAndroid Build Coastguard Worker // A reference to the receive right that is kept alive while a watcher 128*635a8641SAndroid Build Coastguard Worker // is waiting. Null if no event is being watched. 129*635a8641SAndroid Build Coastguard Worker scoped_refptr<WaitableEvent::ReceiveRight> receive_right_; 130*635a8641SAndroid Build Coastguard Worker 131*635a8641SAndroid Build Coastguard Worker // A TYPE_MACH_RECV dispatch source on |receive_right_|. When a receive event 132*635a8641SAndroid Build Coastguard Worker // is delivered, the message queue will be peeked and the bound |callback_| 133*635a8641SAndroid Build Coastguard Worker // may be run. This will be null if nothing is currently being watched. 134*635a8641SAndroid Build Coastguard Worker ScopedDispatchObject<dispatch_source_t> source_; 135*635a8641SAndroid Build Coastguard Worker 136*635a8641SAndroid Build Coastguard Worker // Used to vend a weak pointer for calling InvokeCallback() from the 137*635a8641SAndroid Build Coastguard Worker // |source_| event handler. 138*635a8641SAndroid Build Coastguard Worker WeakPtrFactory<WaitableEventWatcher> weak_ptr_factory_; 139*635a8641SAndroid Build Coastguard Worker #else 140*635a8641SAndroid Build Coastguard Worker // Instantiated in StartWatching(). Set before the callback runs. Reset in 141*635a8641SAndroid Build Coastguard Worker // StopWatching() or StartWatching(). 142*635a8641SAndroid Build Coastguard Worker scoped_refptr<Flag> cancel_flag_; 143*635a8641SAndroid Build Coastguard Worker 144*635a8641SAndroid Build Coastguard Worker // Enqueued in the wait list of the watched WaitableEvent. 145*635a8641SAndroid Build Coastguard Worker AsyncWaiter* waiter_ = nullptr; 146*635a8641SAndroid Build Coastguard Worker 147*635a8641SAndroid Build Coastguard Worker // Kernel of the watched WaitableEvent. 148*635a8641SAndroid Build Coastguard Worker scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; 149*635a8641SAndroid Build Coastguard Worker 150*635a8641SAndroid Build Coastguard Worker // Ensures that StartWatching() and StopWatching() are called on the same 151*635a8641SAndroid Build Coastguard Worker // sequence. 152*635a8641SAndroid Build Coastguard Worker SequenceChecker sequence_checker_; 153*635a8641SAndroid Build Coastguard Worker #endif 154*635a8641SAndroid Build Coastguard Worker 155*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(WaitableEventWatcher); 156*635a8641SAndroid Build Coastguard Worker }; 157*635a8641SAndroid Build Coastguard Worker 158*635a8641SAndroid Build Coastguard Worker } // namespace base 159*635a8641SAndroid Build Coastguard Worker 160*635a8641SAndroid Build Coastguard Worker #endif // BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_ 161