blob: d06bf25207ce7c441b98fda0cf6f0c0c6a858ccb [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/audio_core/wakeup_event.h"
#include <lib/syslog/cpp/macros.h>
#include <zircon/types.h>
namespace media::audio {
namespace {
constexpr zx_signals_t kWakeupEventSignal = ZX_USER_SIGNAL_0;
zx_status_t AssertWakeupEventSignal(const zx::event& event) {
return event.signal(0, kWakeupEventSignal);
}
zx_status_t DeassertWakeupEventSignal(const zx::event& event) {
return event.signal(kWakeupEventSignal, 0);
}
} // namespace
WakeupEvent::WakeupEvent() {
FX_CHECK(zx::event::create(0, &event_) == ZX_OK);
wait_.set_object(event_.get());
wait_.set_trigger(kWakeupEventSignal);
}
zx_status_t WakeupEvent::Activate(async_dispatcher_t* dispatcher, ProcessHandler process_handler) {
process_handler_ = std::move(process_handler);
return wait_.Begin(dispatcher);
}
zx_status_t WakeupEvent::Deactivate() {
process_handler_ = nullptr;
return wait_.Cancel();
}
zx_status_t WakeupEvent::Signal() const { return AssertWakeupEventSignal(event_); }
void WakeupEvent::OnSignals(async_dispatcher_t* dispatcher, async::WaitBase* wait,
zx_status_t status, const zx_packet_signal_t* signal) {
if (status != ZX_OK) {
// Cancellation is normal behavior
if (status != ZX_ERR_CANCELED) {
FX_PLOGS(ERROR, status) << "Async wait failed";
}
return;
}
if (signal->observed & kWakeupEventSignal) {
// Deassert first so that the process handler can reassert if necessary.
status = DeassertWakeupEventSignal(event_);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to clear signals";
return;
}
FX_DCHECK(process_handler_);
zx_status_t status = process_handler_(this);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Process handler failed";
Deactivate();
return;
}
status = wait->Begin(dispatcher);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to wait on signals";
return;
}
}
}
} // namespace media::audio