blob: 9e0ee915c6ba66b506bfb9e6bd7dcf6a92e723dc [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 <trace/observer.h>
#include <zircon/assert.h>
namespace trace {
TraceObserver::TraceObserver() {
wait_.set_handler(fbl::BindMember(this, &TraceObserver::Handle));
}
TraceObserver::~TraceObserver() {
Stop();
}
void TraceObserver::Start(async_t* async, fbl::Closure callback) {
ZX_DEBUG_ASSERT(async);
ZX_DEBUG_ASSERT(callback);
Stop();
async_ = async;
callback_ = fbl::move(callback);
zx_status_t status = zx::event::create(0u, &event_);
ZX_ASSERT(status == ZX_OK);
wait_.set_object(event_.get());
wait_.set_trigger(ZX_EVENT_SIGNALED);
status = wait_.Begin(async_);
ZX_DEBUG_ASSERT(status == ZX_OK);
trace_register_observer(event_.get());
}
void TraceObserver::Stop() {
if (!async_)
return;
trace_unregister_observer(event_.get());
zx_status_t status = wait_.Cancel(async_);
ZX_DEBUG_ASSERT(status == ZX_OK);
async_ = nullptr;
callback_ = nullptr;
}
async_wait_result_t TraceObserver::Handle(async_t* async, zx_status_t status,
const zx_packet_signal_t* signal) {
ZX_DEBUG_ASSERT(status == ZX_OK);
ZX_DEBUG_ASSERT(signal->observed & ZX_EVENT_SIGNALED);
// Clear the signal before invoking the callback.
event_.signal(ZX_EVENT_SIGNALED, 0u);
// Invoke the callback.
callback_();
return ASYNC_WAIT_AGAIN;
}
} // namespace trace