LCOV - code coverage report
Current view: top level - /jenkins/workspace/boost-root/libs/capy/src/ex/detail - timer_service.cpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 55 55
Test Date: 2026-03-11 23:32:43 Functions: 100.0 % 6 6

           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                 : #include <boost/capy/ex/detail/timer_service.hpp>
      11                 : 
      12                 : namespace boost {
      13                 : namespace capy {
      14                 : namespace detail {
      15                 : 
      16 HIT          18 : timer_service::
      17              18 : timer_service(execution_context& ctx)
      18              36 :     : thread_([this] { run(); })
      19                 : {
      20                 :     (void)ctx;
      21              18 : }
      22                 : 
      23                 : timer_service::timer_id
      24             125 : timer_service::
      25                 : schedule_at(
      26                 :     std::chrono::steady_clock::time_point deadline,
      27                 :     std::function<void()> cb)
      28                 : {
      29             125 :     std::lock_guard lock(mutex_);
      30             125 :     auto id = ++next_id_;
      31             125 :     active_ids_.insert(id);
      32             125 :     queue_.push(entry{deadline, id, std::move(cb)});
      33             125 :     cv_.notify_one();
      34             125 :     return id;
      35             125 : }
      36                 : 
      37                 : void
      38              24 : timer_service::
      39                 : cancel(timer_id id)
      40                 : {
      41              24 :     std::unique_lock lock(mutex_);
      42              24 :     if(!active_ids_.contains(id))
      43              18 :         return;
      44               6 :     if(executing_id_ == id)
      45                 :     {
      46                 :         // Callback is running — wait for it to finish.
      47                 :         // run() erases from active_ids_ after execution.
      48               2 :         while(executing_id_ == id)
      49               1 :             cancel_cv_.wait(lock);
      50               1 :         return;
      51                 :     }
      52               5 :     active_ids_.erase(id);
      53              24 : }
      54                 : 
      55                 : void
      56              18 : timer_service::
      57                 : shutdown()
      58                 : {
      59                 :     {
      60              18 :         std::lock_guard lock(mutex_);
      61              18 :         stopped_ = true;
      62              18 :     }
      63              18 :     cv_.notify_one();
      64              18 :     if(thread_.joinable())
      65              18 :         thread_.join();
      66              18 : }
      67                 : 
      68                 : void
      69              18 : timer_service::
      70                 : run()
      71                 : {
      72              18 :     std::unique_lock lock(mutex_);
      73                 :     for(;;)
      74                 :     {
      75             178 :         if(stopped_)
      76              18 :             return;
      77                 : 
      78             160 :         if(queue_.empty())
      79                 :         {
      80              16 :             cv_.wait(lock);
      81              43 :             continue;
      82                 :         }
      83                 : 
      84             144 :         auto deadline = queue_.top().deadline;
      85             144 :         auto now = std::chrono::steady_clock::now();
      86             144 :         if(deadline > now)
      87                 :         {
      88              25 :             cv_.wait_until(lock, deadline);
      89              25 :             continue;
      90                 :         }
      91                 : 
      92                 :         // Pop the entry (const_cast needed because priority_queue::top is const)
      93             119 :         auto e = std::move(const_cast<entry&>(queue_.top()));
      94             119 :         queue_.pop();
      95                 : 
      96                 :         // Skip if cancelled (no longer in active set)
      97             119 :         if(!active_ids_.contains(e.id))
      98               2 :             continue;
      99                 : 
     100             117 :         executing_id_ = e.id;
     101             117 :         lock.unlock();
     102             117 :         e.callback();
     103             117 :         lock.lock();
     104             117 :         active_ids_.erase(e.id);
     105             117 :         executing_id_ = 0;
     106             117 :         cancel_cv_.notify_all();
     107             279 :     }
     108              18 : }
     109                 : 
     110                 : } // detail
     111                 : } // capy
     112                 : } // boost
        

Generated by: LCOV version 2.3