// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/synchronization/waitable_event.h" #include "base/threading/scoped_blocking_call.h" #include "base/trace_event/base_tracing.h" namespace base { void WaitableEvent::Signal() { // Must be ordered before SignalImpl() to guarantee it's emitted before the // matching TerminatingFlow in TimedWait(). if (!only_used_while_idle_) { TRACE_EVENT_INSTANT("wakeup.flow", "WaitableEvent::Signal", perfetto::Flow::FromPointer(this)); } SignalImpl(); } void WaitableEvent::Wait() { const bool result = TimedWait(TimeDelta::Max()); DCHECK(result) << "TimedWait() should never fail with infinite timeout"; } bool WaitableEvent::TimedWait(TimeDelta wait_delta) { if (wait_delta <= TimeDelta()) return IsSignaled(); // Consider this thread blocked for scheduling purposes. Ignore this for // non-blocking WaitableEvents. absl::optional scoped_blocking_call; if (!only_used_while_idle_) { scoped_blocking_call.emplace(FROM_HERE, BlockingType::MAY_BLOCK); } const bool result = TimedWaitImpl(wait_delta); if (result && !only_used_while_idle_) { TRACE_EVENT_INSTANT("wakeup.flow", "WaitableEvent::Wait Complete", perfetto::TerminatingFlow::FromPointer(this)); } return result; } } // namespace base