waitable_event.h 10 KB

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