1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIB_FIT_SINGLE_THREADED_EXECUTOR_H_ 6 #define LIB_FIT_SINGLE_THREADED_EXECUTOR_H_ 7 8 #include <utility> 9 10 #include "promise.h" 11 #include "scheduler.h" 12 13 namespace fit { 14 15 // A simple platform-independent single-threaded asynchronous task executor. 16 // 17 // This implementation is designed for use when writing simple single-threaded 18 // platform-independent applications. It may be less efficient or provide 19 // fewer features than more specialized or platform-dependent executors. 20 // 21 // See documentation of |fit::promise| for more information. 22 class single_threaded_executor final : public executor { 23 public: 24 single_threaded_executor(); 25 26 // Destroys the executor along with all of its remaining scheduled tasks 27 // that have yet to complete. 28 ~single_threaded_executor() override; 29 30 // Schedules a task for eventual execution by the executor. 31 // 32 // This method is thread-safe. 33 void schedule_task(pending_task task) override; 34 35 // Runs all scheduled tasks (including additional tasks scheduled while 36 // they run) until none remain. 37 // 38 // This method is thread-safe but must only be called on at most one 39 // thread at a time. 40 void run(); 41 42 single_threaded_executor(const single_threaded_executor&) = delete; 43 single_threaded_executor(single_threaded_executor&&) = delete; 44 single_threaded_executor& operator=(const single_threaded_executor&) = delete; 45 single_threaded_executor& operator=(single_threaded_executor&&) = delete; 46 47 private: 48 class dispatcher_impl; 49 50 // The task context for tasks run by the executor. 51 class context_impl final : public context { 52 public: 53 explicit context_impl(single_threaded_executor* executor); 54 ~context_impl() override; 55 56 single_threaded_executor* executor() const override; 57 suspended_task suspend_task() override; 58 59 private: 60 single_threaded_executor* const executor_; 61 }; 62 63 context_impl context_; 64 dispatcher_impl* const dispatcher_; 65 }; 66 67 // Creates a new |fit::single_threaded_executor|, schedules a promise as a task, 68 // runs all of the executor's scheduled tasks until none remain, then returns 69 // the promise's result. 70 template <typename Continuation> 71 static typename promise_impl<Continuation>::result_type run_single_threaded(promise_impl<Continuation> promise)72run_single_threaded(promise_impl<Continuation> promise) { 73 using result_type = typename promise_impl<Continuation>::result_type; 74 single_threaded_executor exec; 75 result_type saved_result; 76 exec.schedule_task(promise.then([&saved_result](result_type result) { 77 saved_result = std::move(result); 78 })); 79 exec.run(); 80 return saved_result; 81 } 82 83 } // namespace fit 84 85 #endif // LIB_FIT_SINGLE_THREADED_EXECUTOR_H_ 86