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

Generated by: LCOV version 2.3