blob: 9d8e6b27dfc0307ae736345fa283611c0f191811 [file] [log] [blame]
// Copyright 2017 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 "lib/escher/flib/fence_set_listener.h"
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/zx/time.h>
#include "lib/fxl/logging.h"
namespace escher {
FenceSetListener::FenceSetListener(::std::vector<zx::event> fence_listeners)
: fences_(std::move(fence_listeners)) {}
void FenceSetListener::WaitReadyAsync(fxl::Closure ready_callback) {
if (!ready_callback)
return;
// Make sure callback was not set before.
FXL_DCHECK(!ready_callback_);
if (ready()) {
async::PostTask(async_get_default_dispatcher(), std::move(ready_callback));
return;
}
FXL_DCHECK(waiters_.empty());
waiters_.reserve(fences_.size());
int waiter_index = 0;
// Wait for |kFenceSignalled| on each fence.
for (auto& fence : fences_) {
auto wait = std::make_unique<async::Wait>(fence.get(), // handle
kFenceSignalled // trigger
);
wait->set_handler(std::bind(&FenceSetListener::OnFenceSignalled, this,
waiter_index, std::placeholders::_3,
std::placeholders::_4));
zx_status_t status = wait->Begin(async_get_default_dispatcher());
FXL_CHECK(status == ZX_OK);
waiters_.push_back(std::move(wait));
waiter_index++;
}
ready_callback_ = std::move(ready_callback);
}
void FenceSetListener::OnFenceSignalled(size_t waiter_index, zx_status_t status,
const zx_packet_signal* signal) {
if (status == ZX_OK) {
zx_signals_t pending = signal->observed;
FXL_DCHECK(pending & kFenceSignalled);
FXL_DCHECK(ready_callback_);
num_signalled_fences_++;
FXL_DCHECK(waiters_[waiter_index]);
waiters_[waiter_index].reset();
if (ready()) {
fxl::Closure callback = std::move(ready_callback_);
waiters_.clear();
callback();
}
} else {
FXL_LOG(ERROR) << "FenceSetListener::OnFenceSignalled received an "
"error status code: "
<< status;
// TODO(MZ-173): Close the session if there is an error, or if the fence
// is closed.
}
}
} // namespace escher