LCOV - code coverage report
Current view: top level - /jenkins/workspace/boost-root/libs/capy/src/ex - execution_context.cpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 91.4 % 70 64 6
Test Date: 2026-02-17 18:14:47 Functions: 100.0 % 7 7

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.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 HIT        2863 : execution_context::
      18            2863 : execution_context()
      19            2863 :     : frame_alloc_(get_recycling_memory_resource())
      20                 : {
      21            2863 : }
      22                 : 
      23            2863 : execution_context::
      24                 : ~execution_context()
      25                 : {
      26            2863 :     shutdown();
      27            2863 :     destroy();
      28            2863 : }
      29                 : 
      30                 : void
      31            2924 : execution_context::
      32                 : shutdown() noexcept
      33                 : {
      34            2924 :     if(shutdown_)
      35              61 :         return;
      36            2863 :     shutdown_ = true;
      37                 : 
      38            2863 :     service* p = head_;
      39            2898 :     while(p)
      40                 :     {
      41              35 :         p->shutdown();
      42              35 :         p = p->next_;
      43                 :     }
      44                 : }
      45                 : 
      46                 : void
      47            2924 : execution_context::
      48                 : destroy() noexcept
      49                 : {
      50            2924 :     service* p = head_;
      51            2924 :     head_ = nullptr;
      52            2959 :     while(p)
      53                 :     {
      54              35 :         service* next = p->next_;
      55              35 :         delete p;
      56              35 :         p = next;
      57                 :     }
      58            2924 : }
      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 MIS           0 :         delete sp;
      95               0 :         return *p;
      96                 :     }
      97                 : 
      98 HIT          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 MIS           0 :         delete p;
     123               0 :         detail::throw_invalid_argument();
     124                 :     }
     125                 : 
     126 HIT           7 :     p->t0_ = f.t0;
     127               7 :     if(f.t0 != f.t1)
     128                 :     {
     129               1 :         if(find_impl(f.t1))
     130                 :         {
     131 MIS           0 :             delete p;
     132               0 :             detail::throw_invalid_argument();
     133                 :         }
     134 HIT           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