LCOV - code coverage report
Current view: top level - boost/capy/ex - run_sync.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 78.1 % 32 25
Test Date: 2026-01-18 18:26:31 Functions: 50.0 % 10 5

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
       3              : //
       4              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6              : //
       7              : // Official repository: https://github.com/cppalliance/capy
       8              : //
       9              : 
      10              : #ifndef BOOST_CAPY_RUN_SYNC_HPP
      11              : #define BOOST_CAPY_RUN_SYNC_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : #include <boost/capy/ex/any_coro.hpp>
      15              : #include <boost/capy/ex/execution_context.hpp>
      16              : #include <boost/capy/task.hpp>
      17              : 
      18              : #include <coroutine>
      19              : #include <exception>
      20              : #include <type_traits>
      21              : #include <utility>
      22              : 
      23              : namespace boost {
      24              : namespace capy {
      25              : 
      26              : namespace detail {
      27              : 
      28              : /** Trivial execution context for synchronous execution. */
      29              : class sync_context : public execution_context
      30              : {
      31              : };
      32              : 
      33              : /** Trivial executor for synchronous execution.
      34              : 
      35              :     Returns the coroutine handle directly for symmetric transfer,
      36              :     enabling inline execution without scheduling.
      37              : */
      38              : struct sync_executor
      39              : {
      40              :     static sync_context ctx_;
      41              : 
      42            0 :     bool operator==(sync_executor const&) const noexcept { return true; }
      43            0 :     execution_context& context() const noexcept { return ctx_; }
      44            0 :     void on_work_started() const noexcept {}
      45            0 :     void on_work_finished() const noexcept {}
      46              : 
      47           23 :     any_coro dispatch(any_coro h) const
      48              :     {
      49           23 :         return h;
      50              :     }
      51              : 
      52            0 :     void post(any_coro h) const
      53              :     {
      54            0 :         h.resume();
      55            0 :     }
      56              : };
      57              : 
      58              : inline sync_context sync_executor::ctx_;
      59              : 
      60              : /** Synchronous task runner.
      61              : 
      62              :     Runs a coroutine task to completion on the caller's thread,
      63              :     returning the result directly or rethrowing any exception.
      64              : 
      65              :     This class is not intended for direct use. Use the `run_sync()`
      66              :     factory function instead.
      67              : 
      68              :     @par Thread Safety
      69              :     Not thread-safe. The task runs entirely on the calling thread.
      70              : 
      71              :     @see run_sync
      72              : */
      73              : class sync_runner
      74              : {
      75              : public:
      76              :     sync_runner() = default;
      77              : 
      78              :     sync_runner(sync_runner const&) = delete;
      79              :     sync_runner& operator=(sync_runner const&) = delete;
      80              :     sync_runner(sync_runner&&) = default;
      81              :     sync_runner& operator=(sync_runner&&) = default;
      82              : 
      83              :     /** Run a task to completion and return the result.
      84              : 
      85              :         Executes the task synchronously on the calling thread. The task
      86              :         runs to completion before this function returns.
      87              : 
      88              :         @par Exception Safety
      89              :         If the task throws an exception, it is rethrown to the caller.
      90              : 
      91              :         @param t The task to execute.
      92              : 
      93              :         @return The value returned by the task.
      94              : 
      95              :         @throws Any exception thrown by the task.
      96              :     */
      97              :     template<typename T>
      98           23 :     T operator()(task<T> t) &&
      99              :     {
     100           23 :         auto h = t.release();
     101              :         sync_executor ex;
     102              : 
     103           23 :         h.promise().continuation_ = std::noop_coroutine();
     104           23 :         h.promise().ex_ = ex;
     105           23 :         h.promise().caller_ex_ = ex;
     106           23 :         h.promise().needs_dispatch_ = false;
     107              : 
     108           23 :         ex.dispatch(any_coro{h}).resume();
     109              : 
     110           23 :         std::exception_ptr ep = h.promise().ep_;
     111              : 
     112              :         if constexpr (std::is_void_v<T>)
     113              :         {
     114            7 :             h.destroy();
     115            7 :             if (ep)
     116            2 :                 std::rethrow_exception(ep);
     117              :         }
     118              :         else
     119              :         {
     120           16 :             if (ep)
     121              :             {
     122            3 :                 h.destroy();
     123            6 :                 std::rethrow_exception(ep);
     124              :             }
     125           13 :             auto& result_base = static_cast<detail::task_return_base<T>&>(
     126           13 :                 h.promise());
     127           13 :             auto result = std::move(*result_base.result_);
     128           13 :             h.destroy();
     129           15 :             return result;
     130            2 :         }
     131           23 :     }
     132              : };
     133              : 
     134              : } // namespace detail
     135              : 
     136              : /** Create a synchronous task runner.
     137              : 
     138              :     Returns a runner that executes a coroutine task to completion
     139              :     on the caller's thread. The task completes before this function
     140              :     returns, and the result is returned directly.
     141              : 
     142              :     @par Usage
     143              :     @code
     144              :     // Run a task and get the result
     145              :     int value = run_sync()(compute_value());
     146              : 
     147              :     // Run a void task
     148              :     run_sync()(do_work());
     149              : 
     150              :     // Exceptions propagate normally
     151              :     try {
     152              :         run_sync()(failing_task());
     153              :     } catch (std::exception const& e) {
     154              :         // handle error
     155              :     }
     156              :     @endcode
     157              : 
     158              :     @par Thread Safety
     159              :     The task runs entirely on the calling thread. No executor or
     160              :     execution context is required.
     161              : 
     162              :     @return A runner object with `operator()(task<T>)` that returns `T`.
     163              : 
     164              :     @see task
     165              :     @see run_async
     166              :     @see run_on
     167              : */
     168              : inline
     169              : detail::sync_runner
     170           23 : run_sync()
     171              : {
     172           23 :     return detail::sync_runner{};
     173              : }
     174              : 
     175              : } // namespace capy
     176              : } // namespace boost
     177              : 
     178              : #endif
        

Generated by: LCOV version 2.3