waitable_event_watcher.h 5.3 KB

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