LCOV - code coverage report
Current view: top level - corosio/native - native_timer.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 93.3 % 30 28 2
Test Date: 2026-05-29 17:59:39 Functions: 88.9 % 18 16 2

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Steve Gerbino
       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/corosio
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_COROSIO_NATIVE_NATIVE_TIMER_HPP
      11                 : #define BOOST_COROSIO_NATIVE_NATIVE_TIMER_HPP
      12                 : 
      13                 : #include <boost/corosio/timer.hpp>
      14                 : #include <boost/corosio/backend.hpp>
      15                 : #include <boost/corosio/detail/timer_service.hpp>
      16                 : 
      17                 : namespace boost::corosio {
      18                 : 
      19                 : /** An asynchronous timer with devirtualized wait operations.
      20                 : 
      21                 :     This class template inherits from @ref timer and shadows the
      22                 :     `wait` operation with a version that calls the backend
      23                 :     implementation directly, allowing the compiler to inline
      24                 :     through the entire call chain.
      25                 : 
      26                 :     Non-async operations (`cancel`, `expires_at`, `expires_after`)
      27                 :     remain unchanged and dispatch through the compiled library.
      28                 : 
      29                 :     A `native_timer` IS-A `timer` and can be passed to any function
      30                 :     expecting `timer&`.
      31                 : 
      32                 :     @tparam Backend A backend tag value (e.g., `epoll`).
      33                 :         The timer implementation is backend-independent; the
      34                 :         tag selects the concrete impl type for devirtualization.
      35                 : 
      36                 :     @par Thread Safety
      37                 :     Same as @ref timer.
      38                 : 
      39                 :     @see timer, epoll_t, iocp_t
      40                 : */
      41                 : template<auto Backend>
      42                 : class native_timer : public timer
      43                 : {
      44                 :     using impl_type = detail::timer_service::implementation;
      45                 : 
      46 HIT          10 :     impl_type& get_impl() noexcept
      47                 :     {
      48              10 :         return *static_cast<impl_type*>(h_.get());
      49                 :     }
      50                 : 
      51                 :     struct native_wait_awaitable
      52                 :     {
      53                 :         native_timer& self_;
      54                 :         std::stop_token token_;
      55                 :         mutable std::error_code ec_;
      56                 :         detail::continuation_op cont_op_;
      57                 : 
      58              10 :         explicit native_wait_awaitable(native_timer& self) noexcept
      59              10 :             : self_(self)
      60                 :         {
      61              10 :         }
      62                 : 
      63              10 :         bool await_ready() const noexcept
      64                 :         {
      65              10 :             return token_.stop_requested();
      66                 :         }
      67                 : 
      68              10 :         capy::io_result<> await_resume() const noexcept
      69                 :         {
      70              10 :             if (token_.stop_requested())
      71 MIS           0 :                 return {capy::error::canceled};
      72 HIT          10 :             return {ec_};
      73                 :         }
      74                 : 
      75              10 :         auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
      76                 :             -> std::coroutine_handle<>
      77                 :         {
      78              10 :             token_     = env->stop_token;
      79              10 :             cont_op_.cont.h = h;
      80              10 :             auto& impl = self_.get_impl();
      81                 :             // Fast path: already expired and not in the heap
      82              20 :             if (impl.heap_index_ == timer::implementation::npos &&
      83              20 :                 (impl.expiry_ == (time_point::min)() ||
      84              20 :                  impl.expiry_ <= clock_type::now()))
      85                 :             {
      86               2 :                 ec_    = {};
      87               2 :                 auto d = env->executor;
      88               2 :                 d.post(cont_op_.cont);
      89               2 :                 return std::noop_coroutine();
      90                 :             }
      91               8 :             return impl.wait(h, env->executor, std::move(token_), &ec_, &cont_op_.cont);
      92                 :         }
      93                 :     };
      94                 : 
      95                 : public:
      96                 :     /** Construct a native timer from an execution context.
      97                 : 
      98                 :         @param ctx The execution context that will own this timer.
      99                 :     */
     100              14 :     explicit native_timer(capy::execution_context& ctx) : timer(ctx) {}
     101                 : 
     102                 :     /** Construct a native timer with an initial absolute expiry.
     103                 : 
     104                 :         @param ctx The execution context that will own this timer.
     105                 :         @param t The initial expiry time point.
     106                 :     */
     107                 :     native_timer(capy::execution_context& ctx, time_point t) : timer(ctx, t) {}
     108                 : 
     109                 :     /** Construct a native timer with an initial relative expiry.
     110                 : 
     111                 :         @param ctx The execution context that will own this timer.
     112                 :         @param d The initial expiry duration relative to now.
     113                 :     */
     114                 :     template<class Rep, class Period>
     115               2 :     native_timer(
     116                 :         capy::execution_context& ctx, std::chrono::duration<Rep, Period> d)
     117               2 :         : timer(ctx, d)
     118                 :     {
     119               2 :     }
     120                 : 
     121                 :     /** Move construct.
     122                 : 
     123                 :         @param other The timer to move from.
     124                 : 
     125                 :         @pre No awaitables returned by @p other's methods exist.
     126                 :         @pre The execution context associated with @p other must
     127                 :             outlive this timer.
     128                 :     */
     129 MIS           0 :     native_timer(native_timer&&) noexcept = default;
     130                 : 
     131                 :     /** Move assign.
     132                 : 
     133                 :         @param other The timer to move from.
     134                 : 
     135                 :         @pre No awaitables returned by either `*this` or @p other's
     136                 :             methods exist.
     137                 :         @pre The execution context associated with @p other must
     138                 :             outlive this timer.
     139                 :     */
     140                 :     native_timer& operator=(native_timer&&) noexcept = default;
     141                 : 
     142                 :     native_timer(native_timer const&)            = delete;
     143                 :     native_timer& operator=(native_timer const&) = delete;
     144                 : 
     145                 :     /** Wait for the timer to expire.
     146                 : 
     147                 :         Calls the backend implementation directly, bypassing virtual
     148                 :         dispatch. Otherwise identical to @ref timer::wait.
     149                 : 
     150                 :         @return An awaitable yielding `io_result<>`.
     151                 : 
     152                 :         This timer must outlive the returned awaitable.
     153                 :     */
     154 HIT          10 :     auto wait()
     155                 :     {
     156              10 :         return native_wait_awaitable(*this);
     157                 :     }
     158                 : };
     159                 : 
     160                 : } // namespace boost::corosio
     161                 : 
     162                 : #endif
        

Generated by: LCOV version 2.3