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 % 62 62
Test Date: 2026-03-12 20:08:21 Functions: 100.0 % 9 9

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

Generated by: LCOV version 2.3