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

Generated by: LCOV version 2.3