1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_ 6 #define BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_ 7 8 #include "base/base_export.h" 9 #include "base/macros.h" 10 #include "base/sequence_checker.h" 11 #include "build/build_config.h" 12 13 #if defined(OS_WIN) 14 #include "base/win/object_watcher.h" 15 #else 16 #include "base/callback.h" 17 #include "base/synchronization/waitable_event.h" 18 #endif 19 20 namespace base { 21 22 class Flag; 23 class AsyncWaiter; 24 class WaitableEvent; 25 26 // This class provides a way to wait on a WaitableEvent asynchronously. 27 // 28 // Each instance of this object can be waiting on a single WaitableEvent. When 29 // the waitable event is signaled, a callback is invoked on the sequence that 30 // called StartWatching(). This callback can be deleted by deleting the waiter. 31 // 32 // Typical usage: 33 // 34 // class MyClass { 35 // public: 36 // void DoStuffWhenSignaled(WaitableEvent *waitable_event) { 37 // watcher_.StartWatching(waitable_event, 38 // base::Bind(&MyClass::OnWaitableEventSignaled, this); 39 // } 40 // private: 41 // void OnWaitableEventSignaled(WaitableEvent* waitable_event) { 42 // // OK, time to do stuff! 43 // } 44 // base::WaitableEventWatcher watcher_; 45 // }; 46 // 47 // In the above example, MyClass wants to "do stuff" when waitable_event 48 // becomes signaled. WaitableEventWatcher makes this task easy. When MyClass 49 // goes out of scope, the watcher_ will be destroyed, and there is no need to 50 // worry about OnWaitableEventSignaled being called on a deleted MyClass 51 // pointer. 52 // 53 // BEWARE: With automatically reset WaitableEvents, a signal may be lost if it 54 // occurs just before a WaitableEventWatcher is deleted. There is currently no 55 // safe way to stop watching an automatic reset WaitableEvent without possibly 56 // missing a signal. 57 // 58 // NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on 59 // it with a Watcher. It will act as if the event was never signaled. 60 61 class BASE_EXPORT WaitableEventWatcher 62 #if defined(OS_WIN) 63 : public win::ObjectWatcher::Delegate 64 #endif 65 { 66 public: 67 typedef Callback<void(WaitableEvent*)> EventCallback; 68 WaitableEventWatcher(); 69 70 #if defined(OS_WIN) 71 ~WaitableEventWatcher() override; 72 #else 73 ~WaitableEventWatcher(); 74 #endif 75 76 // When |event| is signaled, |callback| is called on the sequence that called 77 // StartWatching(). 78 bool StartWatching(WaitableEvent* event, const EventCallback& callback); 79 80 // Cancel the current watch. Must be called from the same sequence which 81 // started the watch. 82 // 83 // Does nothing if no event is being watched, nor if the watch has completed. 84 // The callback will *not* be called for the current watch after this 85 // function returns. Since the callback runs on the same sequence as this 86 // function, it cannot be called during this function either. 87 void StopWatching(); 88 89 private: 90 #if defined(OS_WIN) 91 void OnObjectSignaled(HANDLE h) override; 92 93 win::ObjectWatcher watcher_; 94 EventCallback callback_; 95 WaitableEvent* event_ = nullptr; 96 #else 97 // Instantiated in StartWatching(). Set before the callback runs. Reset in 98 // StopWatching() or StartWatching(). 99 scoped_refptr<Flag> cancel_flag_; 100 101 // Enqueued in the wait list of the watched WaitableEvent. 102 AsyncWaiter* waiter_ = nullptr; 103 104 // Kernel of the watched WaitableEvent. 105 scoped_refptr<WaitableEvent::WaitableEventKernel> kernel_; 106 107 // Ensures that StartWatching() and StopWatching() are called on the same 108 // sequence. 109 SequenceChecker sequence_checker_; 110 #endif 111 112 DISALLOW_COPY_AND_ASSIGN(WaitableEventWatcher); 113 }; 114 115 } // namespace base 116 117 #endif // BASE_SYNCHRONIZATION_WAITABLE_EVENT_WATCHER_H_ 118