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-15 18:27:21 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           26 : execution_context::
      17              : execution_context() = default;
      18              : 
      19           26 : execution_context::
      20              : ~execution_context()
      21              : {
      22           26 :     shutdown();
      23           26 :     destroy();
      24           26 : }
      25              : 
      26              : void
      27           40 : execution_context::
      28              : shutdown() noexcept
      29              : {
      30           40 :     if(shutdown_)
      31           14 :         return;
      32           26 :     shutdown_ = true;
      33              : 
      34           26 :     service* p = head_;
      35           41 :     while(p)
      36              :     {
      37           15 :         p->shutdown();
      38           15 :         p = p->next_;
      39              :     }
      40              : }
      41              : 
      42              : void
      43           40 : execution_context::
      44              : destroy() noexcept
      45              : {
      46           40 :     service* p = head_;
      47           40 :     head_ = nullptr;
      48           55 :     while(p)
      49              :     {
      50           15 :         service* next = p->next_;
      51           15 :         delete p;
      52           15 :         p = next;
      53              :     }
      54           40 : }
      55              : 
      56              : execution_context::service*
      57           67 : execution_context::
      58              : find_impl(std::type_index ti) const noexcept
      59              : {
      60           67 :     auto p = head_;
      61           74 :     while(p)
      62              :     {
      63           37 :         if(p->t0_ == ti || p->t1_ == ti)
      64           30 :             break;
      65            7 :         p = p->next_;
      66              :     }
      67           67 :     return p;
      68              : }
      69              : 
      70              : execution_context::service&
      71           17 : execution_context::
      72              : use_service_impl(factory& f)
      73              : {
      74           17 :     std::unique_lock<std::mutex> lock(mutex_);
      75              : 
      76           17 :     if(auto* p = find_impl(f.t0))
      77            9 :         return *p;
      78              : 
      79            8 :     lock.unlock();
      80              : 
      81              :     // Create the service outside lock, enabling nested calls
      82            8 :     service* sp = f.create(*this);
      83            8 :     sp->t0_ = f.t0;
      84            8 :     sp->t1_ = f.t1;
      85              : 
      86            8 :     lock.lock();
      87              : 
      88            8 :     if(auto* p = find_impl(f.t0))
      89              :     {
      90            0 :         delete sp;
      91            0 :         return *p;
      92              :     }
      93              : 
      94            8 :     sp->next_ = head_;
      95            8 :     head_ = sp;
      96              : 
      97            8 :     return *sp;
      98           17 : }
      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