Flutter Engine
waitable_event.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 // Provides classes with functionality analogous to (but much more limited than)
6 // Chromium's |base::WaitableEvent|, which in turn provides functionality
7 // analogous to Windows's Event. (Unlike these two, we have separate types for
8 // the manual- and auto-reset versions.)
9 
10 #ifndef FLUTTER_FML_SYNCHRONIZATION_WAITABLE_EVENT_H_
11 #define FLUTTER_FML_SYNCHRONIZATION_WAITABLE_EVENT_H_
12 
13 #include <condition_variable>
14 #include <mutex>
15 
16 #include "flutter/fml/macros.h"
17 #include "flutter/fml/time/time_delta.h"
18 
19 namespace fml {
20 
21 // AutoResetWaitableEvent ------------------------------------------------------
22 
23 // An event that can be signaled and waited on. This version automatically
24 // returns to the unsignaled state after unblocking one waiter. (This is similar
25 // to Windows's auto-reset Event, which is also imitated by Chromium's
26 // auto-reset |base::WaitableEvent|. However, there are some limitations -- see
27 // |Signal()|.) This class is thread-safe.
29  public:
32 
33  // Put the event in the signaled state. Exactly one |Wait()| will be unblocked
34  // and the event will be returned to the unsignaled state.
35  //
36  // Notes (these are arguably bugs, but not worth working around):
37  // * That |Wait()| may be one that occurs on the calling thread, *after* the
38  // call to |Signal()|.
39  // * A |Signal()|, followed by a |Reset()|, may cause *no* waiting thread to
40  // be unblocked.
41  // * We rely on pthreads's queueing for picking which waiting thread to
42  // unblock, rather than enforcing FIFO ordering.
43  void Signal();
44 
45  // Put the event into the unsignaled state. Generally, this is not recommended
46  // on an auto-reset event (see notes above).
47  void Reset();
48 
49  // Blocks the calling thread until the event is signaled. Upon unblocking, the
50  // event is returned to the unsignaled state, so that (unless |Reset()| is
51  // called) each |Signal()| unblocks exactly one |Wait()|.
52  void Wait();
53 
54  // Like |Wait()|, but with a timeout. Also unblocks if |timeout| expires
55  // without being signaled in which case it returns true (otherwise, it returns
56  // false).
57  bool WaitWithTimeout(TimeDelta timeout);
58 
59  // Returns whether this event is in a signaled state or not. For use in tests
60  // only (in general, this is racy). Note: Unlike
61  // |base::WaitableEvent::IsSignaled()|, this doesn't reset the signaled state.
62  bool IsSignaledForTest();
63 
64  private:
65  std::condition_variable cv_;
66  std::mutex mutex_;
67 
68  // True if this event is in the signaled state.
69  bool signaled_ = false;
70 
71  FML_DISALLOW_COPY_AND_ASSIGN(AutoResetWaitableEvent);
72 };
73 
74 // ManualResetWaitableEvent ----------------------------------------------------
75 
76 // An event that can be signaled and waited on. This version remains signaled
77 // until explicitly reset. (This is similar to Windows's manual-reset Event,
78 // which is also imitated by Chromium's manual-reset |base::WaitableEvent|.)
79 // This class is thread-safe.
81  public:
84 
85  // Put the event into the unsignaled state.
86  void Reset();
87 
88  // Put the event in the signaled state. If this is a manual-reset event, it
89  // wakes all waiting threads (blocked on |Wait()| or |WaitWithTimeout()|).
90  // Otherwise, it wakes a single waiting thread (and returns to the unsignaled
91  // state), if any; if there are none, it remains signaled.
92  void Signal();
93 
94  // Blocks the calling thread until the event is signaled.
95  void Wait();
96 
97  // Like |Wait()|, but with a timeout. Also unblocks if |timeout| expires
98  // without being signaled in which case it returns true (otherwise, it returns
99  // false).
100  bool WaitWithTimeout(TimeDelta timeout);
101 
102  // Returns whether this event is in a signaled state or not. For use in tests
103  // only (in general, this is racy).
104  bool IsSignaledForTest();
105 
106  private:
107  std::condition_variable cv_;
108  std::mutex mutex_;
109 
110  // True if this event is in the signaled state.
111  bool signaled_ = false;
112 
113  // While |std::condition_variable::notify_all()| (|pthread_cond_broadcast()|)
114  // will wake all waiting threads, one has to deal with spurious wake-ups.
115  // Checking |signaled_| isn't sufficient, since another thread may have been
116  // awoken and (manually) reset |signaled_|. This is a counter that is
117  // incremented in |Signal()| before calling
118  // |std::condition_variable::notify_all()|. A waiting thread knows it was
119  // awoken if |signal_id_| is different from when it started waiting.
120  unsigned signal_id_ = 0u;
121 
123 };
124 
125 } // namespace fml
126 
127 #endif // FLUTTER_FML_SYNCHRONIZATION_WAITABLE_EVENT_H_
bool WaitWithTimeout(TimeDelta timeout)
Definition: ascii_trie.cc:9
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27