LCOV - code coverage report
Current view: top level - libs/capy/src/ex - execution_context.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 91.0 % 67 61
Test Date: 2026-01-18 18:26:31 Functions: 100.0 % 7 7

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
       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/execution_context.hpp>
      11              : #include <boost/capy/detail/except.hpp>
      12              : 
      13              : namespace boost {
      14              : namespace capy {
      15              : 
      16           55 : execution_context::
      17              : execution_context() = default;
      18              : 
      19           55 : execution_context::
      20              : ~execution_context()
      21              : {
      22           55 :     shutdown();
      23           55 :     destroy();
      24           55 : }
      25              : 
      26              : void
      27           93 : execution_context::
      28              : shutdown() noexcept
      29              : {
      30           93 :     if(shutdown_)
      31           38 :         return;
      32           55 :     shutdown_ = true;
      33              : 
      34           55 :     service* p = head_;
      35           88 :     while(p)
      36              :     {
      37           33 :         p->shutdown();
      38           33 :         p = p->next_;
      39              :     }
      40              : }
      41              : 
      42              : void
      43           93 : execution_context::
      44              : destroy() noexcept
      45              : {
      46           93 :     service* p = head_;
      47           93 :     head_ = nullptr;
      48          126 :     while(p)
      49              :     {
      50           33 :         service* next = p->next_;
      51           33 :         delete p;
      52           33 :         p = next;
      53              :     }
      54           93 : }
      55              : 
      56              : execution_context::service*
      57          110 : execution_context::
      58              : find_impl(std::type_index ti) const noexcept
      59              : {
      60          110 :     auto p = head_;
      61          117 :     while(p)
      62              :     {
      63           44 :         if(p->t0_ == ti || p->t1_ == ti)
      64           37 :             break;
      65            7 :         p = p->next_;
      66              :     }
      67          110 :     return p;
      68              : }
      69              : 
      70              : execution_context::service&
      71           42 : execution_context::
      72              : use_service_impl(factory& f)
      73              : {
      74           42 :     std::unique_lock<std::mutex> lock(mutex_);
      75              : 
      76           42 :     if(auto* p = find_impl(f.t0))
      77           16 :         return *p;
      78              : 
      79           26 :     lock.unlock();
      80              : 
      81              :     // Create the service outside lock, enabling nested calls
      82           26 :     service* sp = f.create(*this);
      83           26 :     sp->t0_ = f.t0;
      84           26 :     sp->t1_ = f.t1;
      85              : 
      86           26 :     lock.lock();
      87              : 
      88           26 :     if(auto* p = find_impl(f.t0))
      89              :     {
      90            0 :         delete sp;
      91            0 :         return *p;
      92              :     }
      93              : 
      94           26 :     sp->next_ = head_;
      95           26 :     head_ = sp;
      96              : 
      97           26 :     return *sp;
      98           42 : }
      99              : 
     100              : execution_context::service&
     101           10 : execution_context::
     102              : make_service_impl(factory& f)
     103              : {
     104              :     {
     105           10 :         std::lock_guard<std::mutex> lock(mutex_);
     106           10 :         if(find_impl(f.t0))
     107            2 :             detail::throw_invalid_argument();
     108            8 :         if(f.t0 != f.t1 && find_impl(f.t1))
     109            1 :             detail::throw_invalid_argument();
     110           10 :     }
     111              : 
     112              :     // Unlocked to allow nested service creation from constructor
     113            7 :     service* p = f.create(*this);
     114              : 
     115            7 :     std::lock_guard<std::mutex> lock(mutex_);
     116            7 :     if(find_impl(f.t0))
     117              :     {
     118            0 :         delete p;
     119            0 :         detail::throw_invalid_argument();
     120              :     }
     121              : 
     122            7 :     p->t0_ = f.t0;
     123            7 :     if(f.t0 != f.t1)
     124              :     {
     125            1 :         if(find_impl(f.t1))
     126              :         {
     127            0 :             delete p;
     128            0 :             detail::throw_invalid_argument();
     129              :         }
     130            1 :         p->t1_ = f.t1;
     131              :     }
     132              :     else
     133              :     {
     134            6 :         p->t1_ = f.t0;
     135              :     }
     136              : 
     137            7 :     p->next_ = head_;
     138            7 :     head_ = p;
     139              : 
     140            7 :     return *p;
     141            7 : }
     142              : 
     143              : } // namespace capy
     144              : } // namespace boost
        

Generated by: LCOV version 2.3