1 // Copyright 2022 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/synchronization/waitable_event.h" 6 7 #include "base/threading/scoped_blocking_call.h" 8 #include "base/trace_event/base_tracing.h" 9 10 namespace base { 11 Signal()12void WaitableEvent::Signal() { 13 // Must be ordered before SignalImpl() to guarantee it's emitted before the 14 // matching TerminatingFlow in TimedWait(). 15 if (!only_used_while_idle_) { 16 TRACE_EVENT_INSTANT("wakeup.flow", "WaitableEvent::Signal", 17 perfetto::Flow::FromPointer(this)); 18 } 19 SignalImpl(); 20 } 21 Wait()22void WaitableEvent::Wait() { 23 const bool result = TimedWait(TimeDelta::Max()); 24 DCHECK(result) << "TimedWait() should never fail with infinite timeout"; 25 } 26 TimedWait(TimeDelta wait_delta)27bool WaitableEvent::TimedWait(TimeDelta wait_delta) { 28 if (wait_delta <= TimeDelta()) 29 return IsSignaled(); 30 31 // Consider this thread blocked for scheduling purposes. Ignore this for 32 // non-blocking WaitableEvents. 33 absl::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives> 34 scoped_blocking_call; 35 if (!only_used_while_idle_) { 36 scoped_blocking_call.emplace(FROM_HERE, BlockingType::MAY_BLOCK); 37 } 38 39 const bool result = TimedWaitImpl(wait_delta); 40 41 if (result && !only_used_while_idle_) { 42 TRACE_EVENT_INSTANT("wakeup.flow", "WaitableEvent::Wait Complete", 43 perfetto::TerminatingFlow::FromPointer(this)); 44 } 45 46 return result; 47 } 48 49 } // namespace base 50