blob: f7a5ea09fc74c0c8683eed7c76a0e7a88cc7716c [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.
#ifndef SRC_PERFORMANCE_TRACE_MANAGER_UTIL_H_
#define SRC_PERFORMANCE_TRACE_MANAGER_UTIL_H_
#include <fuchsia/tracing/controller/cpp/fidl.h>
#include <lib/async/cpp/executor.h>
#include <lib/async/cpp/time.h>
#include <lib/fpromise/promise.h>
#include <lib/stdcompat/span.h>
#include <lib/zx/socket.h>
#include <iosfwd>
namespace tracing {
namespace controller = fuchsia::tracing::controller;
enum class TransferStatus {
// The transfer is complete.
kComplete,
// An error was detected with the provider, ignore its contribution to
// trace output.
kProviderError,
// Writing of trace data to the receiver failed in an unrecoverable way.
kWriteError,
// The receiver of the transfer went away.
kReceiverDead,
};
std::ostream& operator<<(std::ostream& out, TransferStatus status);
std::ostream& operator<<(std::ostream& out, fuchsia::tracing::BufferDisposition disposition);
std::ostream& operator<<(std::ostream& out, controller::SessionState state);
struct ResultTimedOut {};
template <typename Promise>
class timeout_continuation final {
public:
timeout_continuation(async::Executor& executor, Promise promise, zx::duration d)
: executor_(executor),
promise_(std::move(promise)),
deadline_(async::Now(executor.dispatcher()) + d) {}
fpromise::result<typename Promise::result_type, ResultTimedOut> operator()(
fpromise::context& context) {
auto res = promise_(context);
if (res.is_pending()) {
if (deadline_ <= async::Now(executor_.dispatcher())) {
return fpromise::error(ResultTimedOut{});
}
// If a task requires multiple wakeups to complete, we shouldn't set multiple timeouts.
if (!timeout_scheduled_) {
executor_.schedule_task(executor_.MakePromiseForTime(deadline_).then(
[token = context.suspend_task()](fpromise::result<void, void>&) mutable {
token.resume_task();
}));
timeout_scheduled_ = true;
}
return fpromise::pending();
}
return fpromise::ok(res);
}
private:
bool timeout_scheduled_{false};
async::Executor& executor_;
Promise promise_;
zx::time deadline_;
};
template <typename Promise>
inline fpromise::promise_impl<timeout_continuation<Promise>> with_timeout(async::Executor& executor,
Promise promise,
zx::duration d) {
return make_promise_with_continuation(
timeout_continuation<Promise>(executor, std::move(promise), d));
}
} // namespace tracing
#endif // SRC_PERFORMANCE_TRACE_MANAGER_UTIL_H_