LCOV - code coverage report
Current view: top level - src/detail - cached_initiator.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 96.2 % 26 25
Test Date: 2026-02-06 05:04:16 Functions: 90.0 % 20 18

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2024 Vinnie Falco (vinnie.falco@gmail.com)
       3              : //
       4              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5              : // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
       6              : //
       7              : // Official repository: https://github.com/cppalliance/corosio
       8              : //
       9              : 
      10              : #ifndef BOOST_COROSIO_DETAIL_CACHED_INITIATOR_HPP
      11              : #define BOOST_COROSIO_DETAIL_CACHED_INITIATOR_HPP
      12              : 
      13              : #include <coroutine>
      14              : #include <cstddef>
      15              : 
      16              : namespace boost::corosio::detail {
      17              : 
      18              : /** Cached initiator coroutine frame with RAII cleanup.
      19              : 
      20              :     Manages the lifecycle of a cached coroutine frame used for I/O
      21              :     initiator coroutines. Automatically destroys the coroutine handle
      22              :     and frees the cached frame memory on destruction.
      23              : */
      24              : struct cached_initiator
      25              : {
      26              :     void* frame = nullptr;
      27              :     std::coroutine_handle<> handle;
      28              : 
      29        20092 :     ~cached_initiator()
      30              :     {
      31        20092 :         if (handle)
      32           78 :             handle.destroy();
      33        20092 :         if (frame)
      34           78 :             ::operator delete(frame);
      35        20092 :     }
      36              : 
      37        20092 :     cached_initiator() = default;
      38              :     cached_initiator(cached_initiator const&) = delete;
      39              :     cached_initiator& operator=(cached_initiator const&) = delete;
      40              : 
      41              :     /** Start initiator coroutine that calls Fn on impl.
      42              : 
      43              :         Destroys any existing coroutine, creates a new initiator that
      44              :         will call the specified member function, and returns the handle
      45              :         for symmetric transfer.
      46              : 
      47              :         @tparam Fn Member function pointer to call (e.g., &Impl::do_read_io)
      48              :         @param impl Pointer to the I/O object implementation
      49              :         @return Coroutine handle for symmetric transfer
      50              :     */
      51              :     template<auto Fn, class Impl>
      52       230235 :     std::coroutine_handle<> start(Impl* impl)
      53              :     {
      54       230235 :         if (handle)
      55       230157 :             handle.destroy();
      56       230235 :         auto initiator = make_initiator_coro<Fn>(frame, impl);
      57       230235 :         handle = initiator.h;
      58       460470 :         return initiator.h;
      59              :     }
      60              : 
      61              : private:
      62              :     template<class Impl, auto Fn>
      63              :     struct initiator_coro
      64              :     {
      65              :         struct promise_type
      66              :         {
      67              :             Impl* impl;
      68              : 
      69       230235 :             static void* operator new(std::size_t n, void*& cached, Impl*)
      70              :             {
      71       230235 :                 if (!cached)
      72           78 :                     cached = ::operator new(n);
      73       230235 :                 return cached;
      74              :             }
      75              : 
      76       230235 :             static void operator delete(void*) noexcept {}
      77              : 
      78       230235 :             std::suspend_always initial_suspend() noexcept { return {}; }
      79       230235 :             std::suspend_always final_suspend() noexcept { return {}; }
      80              : 
      81       230235 :             initiator_coro get_return_object()
      82              :             {
      83       230235 :                 return {std::coroutine_handle<promise_type>::from_promise(*this)};
      84              :             }
      85              : 
      86       230235 :             void return_void() {}
      87            0 :             void unhandled_exception() { std::terminate(); }
      88              :         };
      89              : 
      90              :         using handle_type = std::coroutine_handle<promise_type>;
      91              :         handle_type h;
      92              :     };
      93              : 
      94              :     template<auto Fn, class Impl>
      95       230235 :     static initiator_coro<Impl, Fn> make_initiator_coro(void*&, Impl* impl)
      96              :     {
      97              :         (impl->*Fn)();
      98              :         co_return;
      99       460470 :     }
     100              : };
     101              : 
     102              : } // namespace boost::corosio::detail
     103              : 
     104              : #endif
        

Generated by: LCOV version 2.3