libs/capy/src/ex/execution_context.cpp

91.4% Lines (64/70) 100.0% Functions (7/7) 78.7% Branches (37/47)
libs/capy/src/ex/execution_context.cpp
Line Branch Hits 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
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 107 times.
165 if(shutdown_)
35 58 return;
36 107 shutdown_ = true;
37
38 107 service* p = head_;
39
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 107 times.
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
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 165 times.
200 while(p)
53 {
54 35 service* next = p->next_;
55
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
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
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 77 times.
120 while(p)
66 {
67
6/6
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 32 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 7 times.
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
1/1
✓ Branch 1 taken 42 times.
42 std::unique_lock<std::mutex> lock(mutex_);
79
80
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 28 times.
42 if(auto* p = find_impl(f.t0))
81 14 return *p;
82
83
1/1
✓ Branch 1 taken 28 times.
28 lock.unlock();
84
85 // Create the service outside lock, enabling nested calls
86
1/1
✓ Branch 1 taken 28 times.
28 service* sp = f.create(*this);
87 28 sp->t0_ = f.t0;
88 28 sp->t1_ = f.t1;
89
90
1/1
✓ Branch 1 taken 28 times.
28 lock.lock();
91
92
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if(auto* p = find_impl(f.t0))
93 {
94 delete sp;
95 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
1/1
✓ Branch 1 taken 10 times.
10 std::lock_guard<std::mutex> lock(mutex_);
110
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
10 if(find_impl(f.t0))
111 2 detail::throw_invalid_argument();
112
6/6
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 7 times.
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
1/1
✓ Branch 1 taken 7 times.
7 service* p = f.create(*this);
118
119
1/1
✓ Branch 1 taken 7 times.
7 std::lock_guard<std::mutex> lock(mutex_);
120
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if(find_impl(f.t0))
121 {
122 delete p;
123 detail::throw_invalid_argument();
124 }
125
126 7 p->t0_ = f.t0;
127
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 6 times.
7 if(f.t0 != f.t1)
128 {
129
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if(find_impl(f.t1))
130 {
131 delete p;
132 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
149