blob: d48e9a518a1ec70bc1b9cc896ceff4c8941b6c32 [file] [log] [blame]
// Copyright 2018 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 LIB_FIT_PROMISE_INCLUDE_LIB_FPROMISE_SINGLE_THREADED_EXECUTOR_H_
#define LIB_FIT_PROMISE_INCLUDE_LIB_FPROMISE_SINGLE_THREADED_EXECUTOR_H_
#include <utility>
#include "promise.h"
#include "scheduler.h"
namespace fpromise {
// A simple platform-independent single-threaded asynchronous task executor.
//
// This implementation is designed for use when writing simple single-threaded
// platform-independent applications. It may be less efficient or provide
// fewer features than more specialized or platform-dependent executors.
//
// See documentation of |fpromise::promise| for more information.
class single_threaded_executor final : public executor {
public:
single_threaded_executor();
// Destroys the executor along with all of its remaining scheduled tasks
// that have yet to complete.
~single_threaded_executor() override;
// Schedules a task for eventual execution by the executor.
//
// This method is thread-safe.
void schedule_task(pending_task task) override;
// Runs all scheduled tasks (including additional tasks scheduled while
// they run) until none remain.
//
// This method is thread-safe but must only be called on at most one
// thread at a time.
void run();
single_threaded_executor(const single_threaded_executor&) = delete;
single_threaded_executor(single_threaded_executor&&) = delete;
single_threaded_executor& operator=(const single_threaded_executor&) = delete;
single_threaded_executor& operator=(single_threaded_executor&&) = delete;
private:
class dispatcher_impl;
// The task context for tasks run by the executor.
class context_impl final : public context {
public:
explicit context_impl(single_threaded_executor* executor);
~context_impl() override;
single_threaded_executor* executor() const override;
suspended_task suspend_task() override;
private:
single_threaded_executor* const executor_;
};
context_impl context_;
dispatcher_impl* const dispatcher_;
};
// Creates a new |fpromise::single_threaded_executor|, schedules a promise as a task,
// runs all of the executor's scheduled tasks until none remain, then returns
// the promise's result.
template <typename Continuation>
static typename promise_impl<Continuation>::result_type run_single_threaded(
promise_impl<Continuation> promise) {
using result_type = typename promise_impl<Continuation>::result_type;
single_threaded_executor exec;
result_type saved_result;
exec.schedule_task(
promise.then([&saved_result](result_type& result) { saved_result = std::move(result); }));
exec.run();
return saved_result;
}
} // namespace fpromise
#endif // LIB_FIT_PROMISE_INCLUDE_LIB_FPROMISE_SINGLE_THREADED_EXECUTOR_H_