src/ex/execution_context.cpp

88.6% Lines (78/88) 100.0% List of functions (7/7)
execution_context.cpp
f(x) Functions (7)
Line TLA Hits 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 3002x execution_context::
18 3002x execution_context()
19 3002x : frame_alloc_(get_recycling_memory_resource())
20 {
21 3002x }
22
23 3002x execution_context::
24 ~execution_context()
25 {
26 3002x shutdown();
27 3002x destroy();
28 3002x }
29
30 void
31 3159x execution_context::
32 shutdown() noexcept
33 {
34 3159x if(shutdown_)
35 157x return;
36 3002x shutdown_ = true;
37
38 3002x service* p = head_;
39 3065x while(p)
40 {
41 63x p->shutdown();
42 63x p = p->next_;
43 }
44 }
45
46 void
47 3159x execution_context::
48 destroy() noexcept
49 {
50 3159x service* p = head_;
51 3159x head_ = nullptr;
52 3222x while(p)
53 {
54 63x service* next = p->next_;
55 63x delete p;
56 63x p = next;
57 }
58 104247x for(auto& s : slots_)
59 101088x s.store(nullptr, std::memory_order_relaxed);
60 3159x }
61
62 execution_context::service*
63 144x execution_context::
64 find_impl(detail::type_index ti) const noexcept
65 {
66 144x auto p = head_;
67 148x while(p)
68 {
69 10x if(p->t0_ == ti || p->t1_ == ti)
70 6x break;
71 4x p = p->next_;
72 }
73 144x return p;
74 }
75
76 execution_context::service&
77 57x execution_context::
78 use_service_impl(factory& f)
79 {
80 57x std::unique_lock<std::mutex> lock(mutex_);
81
82 57x if(auto* p = find_impl(f.t0))
83 {
84 if(f.slot0 < max_service_slots)
85 slots_[f.slot0].store(p, std::memory_order_release);
86 if(f.slot0 != f.slot1 && f.slot1 < max_service_slots)
87 slots_[f.slot1].store(p, std::memory_order_release);
88 return *p;
89 }
90
91 57x lock.unlock();
92
93 // Create the service outside lock, enabling nested calls
94 57x service* sp = f.create(*this);
95 57x sp->t0_ = f.t0;
96 57x sp->t1_ = f.t1;
97
98 57x lock.lock();
99
100 57x if(auto* p = find_impl(f.t0))
101 {
102 3x if(f.slot0 < max_service_slots)
103 3x slots_[f.slot0].store(p, std::memory_order_release);
104 3x if(f.slot0 != f.slot1 && f.slot1 < max_service_slots)
105 slots_[f.slot1].store(p, std::memory_order_release);
106 3x delete sp;
107 3x return *p;
108 }
109
110 54x sp->next_ = head_;
111 54x head_ = sp;
112
113 54x if(f.slot0 < max_service_slots)
114 54x slots_[f.slot0].store(sp, std::memory_order_release);
115 54x if(f.slot0 != f.slot1 && f.slot1 < max_service_slots)
116 1x slots_[f.slot1].store(sp, std::memory_order_release);
117
118 54x return *sp;
119 57x }
120
121 execution_context::service&
122 12x execution_context::
123 make_service_impl(factory& f)
124 {
125 {
126 12x std::lock_guard<std::mutex> lock(mutex_);
127 12x if(find_impl(f.t0))
128 2x detail::throw_invalid_argument();
129 10x if(f.t0 != f.t1 && find_impl(f.t1))
130 1x detail::throw_invalid_argument();
131 12x }
132
133 // Unlocked to allow nested service creation from constructor
134 9x service* p = f.create(*this);
135
136 9x std::lock_guard<std::mutex> lock(mutex_);
137 9x if(find_impl(f.t0))
138 {
139 delete p;
140 detail::throw_invalid_argument();
141 }
142
143 9x p->t0_ = f.t0;
144 9x if(f.t0 != f.t1)
145 {
146 2x if(find_impl(f.t1))
147 {
148 delete p;
149 detail::throw_invalid_argument();
150 }
151 2x p->t1_ = f.t1;
152 }
153 else
154 {
155 7x p->t1_ = f.t0;
156 }
157
158 9x p->next_ = head_;
159 9x head_ = p;
160
161 9x if(f.slot0 < max_service_slots)
162 9x slots_[f.slot0].store(p, std::memory_order_release);
163 9x if(f.slot0 != f.slot1 && f.slot1 < max_service_slots)
164 2x slots_[f.slot1].store(p, std::memory_order_release);
165
166 9x return *p;
167 9x }
168
169 } // namespace capy
170 } // namespace boost
171