| // 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_ |