xref: /aosp_15_r20/external/webrtc/rtc_base/event.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef RTC_BASE_EVENT_H_
12*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_EVENT_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
17*d9f75844SAndroid Build Coastguard Worker #include <windows.h>
18*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_POSIX)
19*d9f75844SAndroid Build Coastguard Worker #include <pthread.h>
20*d9f75844SAndroid Build Coastguard Worker #else
21*d9f75844SAndroid Build Coastguard Worker #error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
22*d9f75844SAndroid Build Coastguard Worker #endif
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/yield_policy.h"
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker namespace rtc {
27*d9f75844SAndroid Build Coastguard Worker 
28*d9f75844SAndroid Build Coastguard Worker // RTC_DISALLOW_WAIT() utility
29*d9f75844SAndroid Build Coastguard Worker //
30*d9f75844SAndroid Build Coastguard Worker // Sets a stack-scoped flag that disallows use of `rtc::Event::Wait` by means
31*d9f75844SAndroid Build Coastguard Worker // of raising a DCHECK when a call to `rtc::Event::Wait()` is made..
32*d9f75844SAndroid Build Coastguard Worker // This is useful to guard synchronization-free scopes against regressions.
33*d9f75844SAndroid Build Coastguard Worker //
34*d9f75844SAndroid Build Coastguard Worker // Example of what this would catch (`ScopeToProtect` calls `Foo`):
35*d9f75844SAndroid Build Coastguard Worker //
36*d9f75844SAndroid Build Coastguard Worker //  void Foo(TaskQueue* tq) {
37*d9f75844SAndroid Build Coastguard Worker //    Event event;
38*d9f75844SAndroid Build Coastguard Worker //    tq->PostTask([&event]() {
39*d9f75844SAndroid Build Coastguard Worker //      event.Set();
40*d9f75844SAndroid Build Coastguard Worker //    });
41*d9f75844SAndroid Build Coastguard Worker //    event.Wait(Event::kForever);  // <- Will trigger a DCHECK.
42*d9f75844SAndroid Build Coastguard Worker //  }
43*d9f75844SAndroid Build Coastguard Worker //
44*d9f75844SAndroid Build Coastguard Worker //  void ScopeToProtect() {
45*d9f75844SAndroid Build Coastguard Worker //    TaskQueue* tq = GetSomeTaskQueue();
46*d9f75844SAndroid Build Coastguard Worker //    RTC_DISALLOW_WAIT();  // Policy takes effect.
47*d9f75844SAndroid Build Coastguard Worker //    Foo(tq);
48*d9f75844SAndroid Build Coastguard Worker //  }
49*d9f75844SAndroid Build Coastguard Worker //
50*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON
51*d9f75844SAndroid Build Coastguard Worker #define RTC_DISALLOW_WAIT() ScopedDisallowWait disallow_wait_##__LINE__
52*d9f75844SAndroid Build Coastguard Worker #else
53*d9f75844SAndroid Build Coastguard Worker #define RTC_DISALLOW_WAIT()
54*d9f75844SAndroid Build Coastguard Worker #endif
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker class Event {
57*d9f75844SAndroid Build Coastguard Worker  public:
58*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/14366): Consider removing this redundant alias.
59*d9f75844SAndroid Build Coastguard Worker   static constexpr webrtc::TimeDelta kForever =
60*d9f75844SAndroid Build Coastguard Worker       webrtc::TimeDelta::PlusInfinity();
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker   Event();
63*d9f75844SAndroid Build Coastguard Worker   Event(bool manual_reset, bool initially_signaled);
64*d9f75844SAndroid Build Coastguard Worker   Event(const Event&) = delete;
65*d9f75844SAndroid Build Coastguard Worker   Event& operator=(const Event&) = delete;
66*d9f75844SAndroid Build Coastguard Worker   ~Event();
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker   void Set();
69*d9f75844SAndroid Build Coastguard Worker   void Reset();
70*d9f75844SAndroid Build Coastguard Worker 
71*d9f75844SAndroid Build Coastguard Worker   // Waits for the event to become signaled, but logs a warning if it takes more
72*d9f75844SAndroid Build Coastguard Worker   // than `warn_after`, and gives up completely if it takes more than
73*d9f75844SAndroid Build Coastguard Worker   // `give_up_after`. (If `warn_after >= give_up_after`, no warning will be
74*d9f75844SAndroid Build Coastguard Worker   // logged.) Either or both may be `kForever`, which means wait indefinitely.
75*d9f75844SAndroid Build Coastguard Worker   //
76*d9f75844SAndroid Build Coastguard Worker   // Care is taken so that the underlying OS wait call isn't requested to sleep
77*d9f75844SAndroid Build Coastguard Worker   // shorter than `give_up_after`.
78*d9f75844SAndroid Build Coastguard Worker   //
79*d9f75844SAndroid Build Coastguard Worker   // Returns true if the event was signaled, false if there was a timeout or
80*d9f75844SAndroid Build Coastguard Worker   // some other error.
81*d9f75844SAndroid Build Coastguard Worker   bool Wait(webrtc::TimeDelta give_up_after, webrtc::TimeDelta warn_after);
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   // Waits with the given timeout and a reasonable default warning timeout.
Wait(webrtc::TimeDelta give_up_after)84*d9f75844SAndroid Build Coastguard Worker   bool Wait(webrtc::TimeDelta give_up_after) {
85*d9f75844SAndroid Build Coastguard Worker     return Wait(give_up_after, give_up_after.IsPlusInfinity()
86*d9f75844SAndroid Build Coastguard Worker                                    ? webrtc::TimeDelta::Seconds(3)
87*d9f75844SAndroid Build Coastguard Worker                                    : kForever);
88*d9f75844SAndroid Build Coastguard Worker   }
89*d9f75844SAndroid Build Coastguard Worker 
90*d9f75844SAndroid Build Coastguard Worker  private:
91*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
92*d9f75844SAndroid Build Coastguard Worker   HANDLE event_handle_;
93*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_POSIX)
94*d9f75844SAndroid Build Coastguard Worker   pthread_mutex_t event_mutex_;
95*d9f75844SAndroid Build Coastguard Worker   pthread_cond_t event_cond_;
96*d9f75844SAndroid Build Coastguard Worker   const bool is_manual_reset_;
97*d9f75844SAndroid Build Coastguard Worker   bool event_status_;
98*d9f75844SAndroid Build Coastguard Worker #endif
99*d9f75844SAndroid Build Coastguard Worker };
100*d9f75844SAndroid Build Coastguard Worker 
101*d9f75844SAndroid Build Coastguard Worker // These classes are provided for compatibility with Chromium.
102*d9f75844SAndroid Build Coastguard Worker // The rtc::Event implementation is overriden inside of Chromium for the
103*d9f75844SAndroid Build Coastguard Worker // purposes of detecting when threads are blocked that shouldn't be as well as
104*d9f75844SAndroid Build Coastguard Worker // to use the more accurate event implementation that's there than is provided
105*d9f75844SAndroid Build Coastguard Worker // by default on some platforms (e.g. Windows).
106*d9f75844SAndroid Build Coastguard Worker // When building with standalone WebRTC, this class is a noop.
107*d9f75844SAndroid Build Coastguard Worker // For further information, please see the
108*d9f75844SAndroid Build Coastguard Worker // ScopedAllowBaseSyncPrimitives(ForTesting) classes in Chromium.
109*d9f75844SAndroid Build Coastguard Worker class ScopedAllowBaseSyncPrimitives {
110*d9f75844SAndroid Build Coastguard Worker  public:
ScopedAllowBaseSyncPrimitives()111*d9f75844SAndroid Build Coastguard Worker   ScopedAllowBaseSyncPrimitives() {}
~ScopedAllowBaseSyncPrimitives()112*d9f75844SAndroid Build Coastguard Worker   ~ScopedAllowBaseSyncPrimitives() {}
113*d9f75844SAndroid Build Coastguard Worker };
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker class ScopedAllowBaseSyncPrimitivesForTesting {
116*d9f75844SAndroid Build Coastguard Worker  public:
ScopedAllowBaseSyncPrimitivesForTesting()117*d9f75844SAndroid Build Coastguard Worker   ScopedAllowBaseSyncPrimitivesForTesting() {}
~ScopedAllowBaseSyncPrimitivesForTesting()118*d9f75844SAndroid Build Coastguard Worker   ~ScopedAllowBaseSyncPrimitivesForTesting() {}
119*d9f75844SAndroid Build Coastguard Worker };
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON
122*d9f75844SAndroid Build Coastguard Worker class ScopedDisallowWait {
123*d9f75844SAndroid Build Coastguard Worker  public:
124*d9f75844SAndroid Build Coastguard Worker   ScopedDisallowWait() = default;
125*d9f75844SAndroid Build Coastguard Worker 
126*d9f75844SAndroid Build Coastguard Worker  private:
127*d9f75844SAndroid Build Coastguard Worker   class DisallowYieldHandler : public YieldInterface {
128*d9f75844SAndroid Build Coastguard Worker    public:
YieldExecution()129*d9f75844SAndroid Build Coastguard Worker     void YieldExecution() override { RTC_DCHECK_NOTREACHED(); }
130*d9f75844SAndroid Build Coastguard Worker   } handler_;
131*d9f75844SAndroid Build Coastguard Worker   rtc::ScopedYieldPolicy policy{&handler_};
132*d9f75844SAndroid Build Coastguard Worker };
133*d9f75844SAndroid Build Coastguard Worker #endif
134*d9f75844SAndroid Build Coastguard Worker 
135*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
136*d9f75844SAndroid Build Coastguard Worker 
137*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_BASE_EVENT_H_
138