blob: 92801dc951143bea2b006a71da4c9b264df8fa9a [file] [log] [blame]
// Copyright 2022 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/sys/fuzzing/common/async-eventpair.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/time.h>
#include <zircon/errors.h>
#include <zircon/status.h>
namespace fuzzing {
AsyncEventPair::AsyncEventPair(ExecutorPtr executor) : executor_(std::move(executor)) {}
zx::eventpair AsyncEventPair::Create() {
zx::eventpair eventpair;
auto status = zx::eventpair::create(0, &eventpair_, &eventpair);
FX_DCHECK(status == ZX_OK) << zx_status_get_string(status);
return eventpair;
}
void AsyncEventPair::Pair(zx::eventpair&& eventpair) {
FX_DCHECK(eventpair.is_valid());
eventpair_ = std::move(eventpair);
}
void AsyncEventPair::SignalSelf(zx_signals_t to_clear, zx_signals_t to_set) const {
auto status = eventpair_.signal(to_clear, to_set);
FX_DCHECK(status == ZX_OK || status == ZX_ERR_BAD_HANDLE || status == ZX_ERR_PEER_CLOSED)
<< zx_status_get_string(status);
}
void AsyncEventPair::SignalPeer(zx_signals_t to_clear, zx_signals_t to_set) const {
auto status = eventpair_.signal_peer(to_clear, to_set);
FX_DCHECK(status == ZX_OK || status == ZX_ERR_BAD_HANDLE || status == ZX_ERR_PEER_CLOSED)
<< zx_status_get_string(status);
}
zx_signals_t AsyncEventPair::GetSignals(zx_signals_t signals) const {
FX_DCHECK(eventpair_.is_valid());
zx_signals_t observed = 0;
eventpair_.wait_one(signals, zx::time::infinite_past(), &observed);
return observed & signals;
}
ZxPromise<zx_signals_t> AsyncEventPair::WaitFor(zx_signals_t signals) {
return executor_
->MakePromiseWaitHandle(zx::unowned_handle(eventpair_.get()),
signals | ZX_EVENTPAIR_PEER_CLOSED)
.and_then([signals](const zx_packet_signal_t& packet) -> ZxResult<zx_signals_t> {
if (packet.observed & ZX_EVENTPAIR_PEER_CLOSED) {
return fpromise::error(ZX_ERR_PEER_CLOSED);
}
return fpromise::ok(packet.observed & signals);
})
.or_else([this](zx_status_t& status) {
FX_DCHECK(status == ZX_ERR_CANCELED || status == ZX_ERR_BAD_HANDLE ||
status == ZX_ERR_PEER_CLOSED)
<< zx_status_get_string(status);
eventpair_.reset();
return fpromise::error(status);
})
.wrap_with(scope_);
}
} // namespace fuzzing