50 lines
1.5 KiB
C++
50 lines
1.5 KiB
C++
// 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<internal::ScopedBlockingCallWithBaseSyncPrimitives>
|
|
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
|