LCOV - code coverage report
Current view: top level - boost/capy/ex - run_sync.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 25 25
Test Date: 2026-01-17 12:16:19 Functions: 100.0 % 5 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/task.hpp>
      16              : 
      17              : #include <coroutine>
      18              : #include <exception>
      19              : #include <type_traits>
      20              : #include <utility>
      21              : 
      22              : namespace boost {
      23              : namespace capy {
      24              : 
      25              : namespace detail {
      26              : 
      27              : /** Trivial dispatcher for synchronous execution.
      28              : 
      29              :     Returns the coroutine handle directly for symmetric transfer,
      30              :     enabling inline execution without scheduling.
      31              : */
      32              : struct sync_dispatcher
      33              : {
      34           23 :     any_coro operator()(any_coro h) const
      35              :     {
      36           23 :         return h;
      37              :     }
      38              : };
      39              : 
      40              : /** Synchronous task runner.
      41              : 
      42              :     Runs a coroutine task to completion on the caller's thread,
      43              :     returning the result directly or rethrowing any exception.
      44              : 
      45              :     This class is not intended for direct use. Use the `run_sync()`
      46              :     factory function instead.
      47              : 
      48              :     @par Thread Safety
      49              :     Not thread-safe. The task runs entirely on the calling thread.
      50              : 
      51              :     @see run_sync
      52              : */
      53              : class sync_runner
      54              : {
      55              : public:
      56              :     sync_runner() = default;
      57              : 
      58              :     sync_runner(sync_runner const&) = delete;
      59              :     sync_runner& operator=(sync_runner const&) = delete;
      60              :     sync_runner(sync_runner&&) = default;
      61              :     sync_runner& operator=(sync_runner&&) = default;
      62              : 
      63              :     /** Run a task to completion and return the result.
      64              : 
      65              :         Executes the task synchronously on the calling thread. The task
      66              :         runs to completion before this function returns.
      67              : 
      68              :         @par Exception Safety
      69              :         If the task throws an exception, it is rethrown to the caller.
      70              : 
      71              :         @param t The task to execute.
      72              : 
      73              :         @return The value returned by the task.
      74              : 
      75              :         @throws Any exception thrown by the task.
      76              :     */
      77              :     template<typename T>
      78           23 :     T operator()(task<T> t) &&
      79              :     {
      80           23 :         auto h = t.release();
      81              :         sync_dispatcher d;
      82              : 
      83           23 :         h.promise().continuation_ = std::noop_coroutine();
      84           23 :         h.promise().ex_ = d;
      85           23 :         h.promise().caller_ex_ = d;
      86           23 :         h.promise().needs_dispatch_ = false;
      87              : 
      88           23 :         d(any_coro{h}).resume();
      89              : 
      90           23 :         std::exception_ptr ep = h.promise().ep_;
      91              : 
      92              :         if constexpr (std::is_void_v<T>)
      93              :         {
      94            7 :             h.destroy();
      95            7 :             if (ep)
      96            2 :                 std::rethrow_exception(ep);
      97              :         }
      98              :         else
      99              :         {
     100           16 :             if (ep)
     101              :             {
     102            3 :                 h.destroy();
     103            6 :                 std::rethrow_exception(ep);
     104              :             }
     105           13 :             auto& result_base = static_cast<detail::task_return_base<T>&>(
     106           13 :                 h.promise());
     107           13 :             auto result = std::move(*result_base.result_);
     108           13 :             h.destroy();
     109           15 :             return result;
     110            2 :         }
     111           23 :     }
     112              : };
     113              : 
     114              : } // namespace detail
     115              : 
     116              : /** Create a synchronous task runner.
     117              : 
     118              :     Returns a runner that executes a coroutine task to completion
     119              :     on the caller's thread. The task completes before this function
     120              :     returns, and the result is returned directly.
     121              : 
     122              :     @par Usage
     123              :     @code
     124              :     // Run a task and get the result
     125              :     int value = run_sync()(compute_value());
     126              : 
     127              :     // Run a void task
     128              :     run_sync()(do_work());
     129              : 
     130              :     // Exceptions propagate normally
     131              :     try {
     132              :         run_sync()(failing_task());
     133              :     } catch (std::exception const& e) {
     134              :         // handle error
     135              :     }
     136              :     @endcode
     137              : 
     138              :     @par Thread Safety
     139              :     The task runs entirely on the calling thread. No dispatcher or
     140              :     execution context is required.
     141              : 
     142              :     @return A runner object with `operator()(task<T>)` that returns `T`.
     143              : 
     144              :     @see task
     145              :     @see run_async
     146              :     @see run_on
     147              : */
     148              : inline
     149              : detail::sync_runner
     150           23 : run_sync()
     151              : {
     152           23 :     return detail::sync_runner{};
     153              : }
     154              : 
     155              : } // namespace capy
     156              : } // namespace boost
     157              : 
     158              : #endif
        

Generated by: LCOV version 2.3