LCOV - code coverage report
Current view: top level - capy/ex/detail - timer_service.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 5 5
Test Date: 2026-03-11 23:32:43 Functions: 100.0 % 4 4

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Michael Vandeberg
       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_EX_TIMER_SERVICE_HPP
      11                 : #define BOOST_CAPY_EX_TIMER_SERVICE_HPP
      12                 : 
      13                 : #include <boost/capy/detail/config.hpp>
      14                 : #include <boost/capy/ex/execution_context.hpp>
      15                 : 
      16                 : #include <chrono>
      17                 : #include <cstdint>
      18                 : #include <functional>
      19                 : #include <mutex>
      20                 : #include <condition_variable>
      21                 : #include <queue>
      22                 : #include <thread>
      23                 : #include <unordered_set>
      24                 : #include <vector>
      25                 : 
      26                 : namespace boost {
      27                 : namespace capy {
      28                 : namespace detail {
      29                 : 
      30                 : /* Shared timer thread for an execution_context.
      31                 : 
      32                 :    One background std::thread per execution_context. All timeouts
      33                 :    scheduled through this context share the same thread, which sleeps
      34                 :    on a condition variable until the next deadline.
      35                 : 
      36                 :    The timer thread never touches coroutine frames or executors
      37                 :    directly — callbacks are responsible for posting work through
      38                 :    the appropriate executor.
      39                 : */
      40                 : 
      41                 : class BOOST_CAPY_DECL
      42                 :     timer_service
      43                 :     : public execution_context::service
      44                 : {
      45                 : public:
      46                 :     using timer_id = std::uint64_t;
      47                 : 
      48                 :     explicit timer_service(execution_context& ctx);
      49                 : 
      50                 :     /** Schedule a callback to fire after a duration.
      51                 : 
      52                 :         The callback is invoked on the timer service's background
      53                 :         thread. It must not block for extended periods.
      54                 : 
      55                 :         @return An id that can be passed to cancel().
      56                 :     */
      57                 :     template<typename Rep, typename Period>
      58 HIT         125 :     timer_id schedule_after(
      59                 :         std::chrono::duration<Rep, Period> dur,
      60                 :         std::function<void()> cb)
      61                 :     {
      62             125 :         auto deadline = std::chrono::steady_clock::now() + dur;
      63             125 :         return schedule_at(deadline, std::move(cb));
      64                 :     }
      65                 : 
      66                 :     /** Cancel a pending timer.
      67                 : 
      68                 :         After this function returns, the callback is guaranteed
      69                 :         not to be running and will never be invoked. If the
      70                 :         callback is currently executing on the timer thread,
      71                 :         this call blocks until it completes.
      72                 : 
      73                 :         Safe to call with any id, including ids that have
      74                 :         already fired, been cancelled, or were never issued.
      75                 :     */
      76                 :     void cancel(timer_id id);
      77                 : 
      78                 : protected:
      79                 :     void shutdown() override;
      80                 : 
      81                 : private:
      82                 :     struct entry
      83                 :     {
      84                 :         std::chrono::steady_clock::time_point deadline;
      85                 :         timer_id id;
      86                 :         std::function<void()> callback;
      87                 : 
      88             639 :         bool operator>(entry const& o) const noexcept
      89                 :         {
      90             639 :             return deadline > o.deadline;
      91                 :         }
      92                 :     };
      93                 : 
      94                 :     timer_id schedule_at(
      95                 :         std::chrono::steady_clock::time_point deadline,
      96                 :         std::function<void()> cb);
      97                 : 
      98                 :     void run();
      99                 : 
     100                 : // warning C4251: std types need to have dll-interface
     101                 : #ifdef _MSC_VER
     102                 : # pragma warning(push)
     103                 : # pragma warning(disable: 4251)
     104                 : #endif
     105                 :     std::mutex mutex_;
     106                 :     std::condition_variable cv_;
     107                 :     std::condition_variable cancel_cv_;
     108                 :     std::priority_queue<
     109                 :         entry,
     110                 :         std::vector<entry>,
     111                 :         std::greater<>> queue_;
     112                 :     std::unordered_set<timer_id> active_ids_;
     113                 :     timer_id next_id_ = 0;
     114                 :     timer_id executing_id_ = 0;
     115                 :     bool stopped_ = false;
     116                 :     std::thread thread_;
     117                 : #ifdef _MSC_VER
     118                 : # pragma warning(pop)
     119                 : #endif
     120                 : };
     121                 : 
     122                 : } // detail
     123                 : } // capy
     124                 : } // boost
     125                 : 
     126                 : #endif
        

Generated by: LCOV version 2.3