1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2021-2021. Distributed under the Boost |
4 | // Software License, Version 1.0. (See accompanying file |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | // |
7 | // See http://www.boost.org/libs/interprocess for documentation. |
8 | // |
9 | ////////////////////////////////////////////////////////////////////////////// |
10 | |
11 | #ifndef BOOST_INTERPROCESS_TEST_NAMED_CONDITION_HELPERS_HEADER |
12 | #define |
13 | |
14 | #include <boost/interprocess/detail/config_begin.hpp> |
15 | #include <boost/interprocess/sync/cv_status.hpp> |
16 | #include <boost/interprocess/detail/interprocess_tester.hpp> |
17 | #include <boost/interprocess/sync/detail/locks.hpp> |
18 | #include "condition_test_template.hpp" |
19 | #include "named_creation_template.hpp" |
20 | #include "get_process_id_name.hpp" |
21 | |
22 | namespace boost { namespace interprocess { namespace test { |
23 | |
24 | template<class NamedCondition> |
25 | struct condition_deleter |
26 | { |
27 | std::string name; |
28 | |
29 | ~condition_deleter() |
30 | { |
31 | if(name.empty()) |
32 | NamedCondition::remove(test::add_to_process_id_name(name: "named_condition" )); |
33 | else |
34 | NamedCondition::remove(name.c_str()); |
35 | } |
36 | }; |
37 | |
38 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) |
39 | |
40 | template<class NamedCondition> |
41 | struct condition_deleter_w |
42 | { |
43 | std::string name; |
44 | |
45 | ~condition_deleter_w() |
46 | { |
47 | if(name.empty()) |
48 | NamedCondition::remove(test::add_to_process_id_name(L"named_condition" )); |
49 | else |
50 | NamedCondition::remove(name.c_str()); |
51 | } |
52 | }; |
53 | |
54 | #endif //#if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) |
55 | |
56 | |
57 | inline std::string num_to_string(int n) |
58 | { std::stringstream s; s << n; return s.str(); } |
59 | |
60 | //This wrapper is necessary to have a default constructor |
61 | //in generic mutex_test_template functions |
62 | template<class NamedCondition> |
63 | class named_condition_test_wrapper |
64 | : public condition_deleter<NamedCondition>, public NamedCondition |
65 | { |
66 | public: |
67 | |
68 | named_condition_test_wrapper() |
69 | : NamedCondition(open_or_create, |
70 | (test::add_to_process_id_name(name: "test_cond" ) + num_to_string(n: count)).c_str()) |
71 | { |
72 | condition_deleter<NamedCondition>::name += test::add_to_process_id_name(name: "test_cond" ); |
73 | condition_deleter<NamedCondition>::name += num_to_string(n: count); |
74 | ++count; |
75 | } |
76 | |
77 | ~named_condition_test_wrapper() |
78 | { --count; } |
79 | |
80 | |
81 | template <typename L> |
82 | void wait(L& lock) |
83 | { |
84 | ipcdetail::internal_mutex_lock<L> internal_lock(lock); |
85 | NamedCondition::wait(internal_lock); |
86 | } |
87 | |
88 | template <typename L, typename Pr> |
89 | void wait(L& lock, Pr pred) |
90 | { |
91 | ipcdetail::internal_mutex_lock<L> internal_lock(lock); |
92 | NamedCondition::wait(internal_lock, pred); |
93 | } |
94 | |
95 | template <typename L, typename TimePoint> |
96 | bool timed_wait(L& lock, const TimePoint &abs_time) |
97 | { |
98 | ipcdetail::internal_mutex_lock<L> internal_lock(lock); |
99 | return NamedCondition::timed_wait(internal_lock, abs_time); |
100 | } |
101 | |
102 | template <typename L, typename TimePoint, typename Pr> |
103 | bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred) |
104 | { |
105 | ipcdetail::internal_mutex_lock<L> internal_lock(lock); |
106 | return NamedCondition::timed_wait(internal_lock, abs_time, pred); |
107 | } |
108 | |
109 | template <typename L, class TimePoint> |
110 | cv_status wait_until(L& lock, const TimePoint &abs_time) |
111 | { |
112 | ipcdetail::internal_mutex_lock<L> internal_lock(lock); |
113 | return NamedCondition::wait_until(internal_lock, abs_time); |
114 | } |
115 | |
116 | template <typename L, class TimePoint, typename Pr> |
117 | bool wait_until(L& lock, const TimePoint &abs_time, Pr pred) |
118 | { |
119 | ipcdetail::internal_mutex_lock<L> internal_lock(lock); |
120 | return NamedCondition::wait_until(internal_lock, abs_time, pred); |
121 | } |
122 | |
123 | static int count; |
124 | }; |
125 | |
126 | template<class NamedCondition> |
127 | int named_condition_test_wrapper<NamedCondition>::count = 0; |
128 | |
129 | //This wrapper is necessary to have a common constructor |
130 | //in generic named_creation_template functions |
131 | template<class NamedCondition> |
132 | class named_condition_creation_test_wrapper |
133 | : public condition_deleter<NamedCondition>, public NamedCondition |
134 | { |
135 | public: |
136 | named_condition_creation_test_wrapper(create_only_t) |
137 | : NamedCondition(create_only, test::add_to_process_id_name(name: "named_condition" )) |
138 | { ++count_; } |
139 | |
140 | named_condition_creation_test_wrapper(open_only_t) |
141 | : NamedCondition(open_only, test::add_to_process_id_name(name: "named_condition" )) |
142 | { ++count_; } |
143 | |
144 | named_condition_creation_test_wrapper(open_or_create_t) |
145 | : NamedCondition(open_or_create, test::add_to_process_id_name(name: "named_condition" )) |
146 | { ++count_; } |
147 | |
148 | ~named_condition_creation_test_wrapper() { |
149 | if(--count_){ |
150 | ipcdetail::interprocess_tester:: |
151 | dont_close_on_destruction(static_cast<NamedCondition&>(*this)); |
152 | } |
153 | } |
154 | static int count_; |
155 | }; |
156 | |
157 | template<class NamedCondition> |
158 | int named_condition_creation_test_wrapper<NamedCondition>::count_ = 0; |
159 | |
160 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) |
161 | |
162 | //This wrapper is necessary to have a common constructor |
163 | //in generic named_creation_template functions |
164 | template<class NamedCondition> |
165 | class named_condition_creation_test_wrapper_w |
166 | : public condition_deleter_w<NamedCondition>, public NamedCondition |
167 | { |
168 | public: |
169 | named_condition_creation_test_wrapper_w(create_only_t) |
170 | : NamedCondition(create_only, test::add_to_process_id_name(L"named_condition" )) |
171 | { ++count_; } |
172 | |
173 | named_condition_creation_test_wrapper_w(open_only_t) |
174 | : NamedCondition(open_only, test::add_to_process_id_name(L"named_condition" )) |
175 | { ++count_; } |
176 | |
177 | named_condition_creation_test_wrapper_w(open_or_create_t) |
178 | : NamedCondition(open_or_create, test::add_to_process_id_name(L"named_condition" )) |
179 | { ++count_; } |
180 | |
181 | ~named_condition_creation_test_wrapper_w() { |
182 | if(--count_){ |
183 | ipcdetail::interprocess_tester:: |
184 | dont_close_on_destruction(static_cast<NamedCondition&>(*this)); |
185 | } |
186 | } |
187 | static int count_; |
188 | }; |
189 | |
190 | template<class NamedCondition> |
191 | int named_condition_creation_test_wrapper_w<NamedCondition>::count_ = 0; |
192 | |
193 | #endif //#if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) |
194 | |
195 | template<class NamedMutex> |
196 | struct mutex_deleter |
197 | { |
198 | std::string name; |
199 | |
200 | ~mutex_deleter() |
201 | { |
202 | if(name.empty()) |
203 | NamedMutex::remove(test::add_to_process_id_name(name: "named_mutex" )); |
204 | else |
205 | NamedMutex::remove(name.c_str()); |
206 | } |
207 | }; |
208 | |
209 | //This wrapper is necessary to have a default constructor |
210 | //in generic mutex_test_template functions |
211 | template<class NamedMutex> |
212 | class named_mutex_test_wrapper |
213 | : public mutex_deleter<NamedMutex>, public NamedMutex |
214 | { |
215 | public: |
216 | named_mutex_test_wrapper() |
217 | : NamedMutex(open_or_create, |
218 | (test::add_to_process_id_name(name: "test_mutex" ) + num_to_string(n: count)).c_str()) |
219 | { |
220 | mutex_deleter<NamedMutex>::name += test::add_to_process_id_name(name: "test_mutex" ); |
221 | mutex_deleter<NamedMutex>::name += num_to_string(n: count); |
222 | ++count; |
223 | } |
224 | |
225 | typedef NamedMutex internal_mutex_type; |
226 | |
227 | internal_mutex_type &internal_mutex() |
228 | { return *this; } |
229 | |
230 | ~named_mutex_test_wrapper() |
231 | { --count; } |
232 | |
233 | static int count; |
234 | }; |
235 | |
236 | template<class NamedMutex> |
237 | int named_mutex_test_wrapper<NamedMutex>::count = 0; |
238 | |
239 | template<class NamedCondition, class NamedMutex> |
240 | int test_named_condition() |
241 | { |
242 | int ret = 0; |
243 | BOOST_TRY{ |
244 | //Remove previous mutexes and conditions |
245 | NamedMutex::remove(test::add_to_process_id_name(name: "test_mutex0" )); |
246 | NamedCondition::remove(test::add_to_process_id_name(name: "test_cond0" )); |
247 | NamedCondition::remove(test::add_to_process_id_name(name: "test_cond1" )); |
248 | NamedCondition::remove(test::add_to_process_id_name(name: "named_condition" )); |
249 | NamedMutex::remove(test::add_to_process_id_name(name: "named_mutex" )); |
250 | |
251 | test::test_named_creation<test::named_condition_creation_test_wrapper<NamedCondition> >(); |
252 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) |
253 | //Remove previous mutexes and conditions |
254 | NamedMutex::remove(test::add_to_process_id_name("test_mutex0" )); |
255 | NamedCondition::remove(test::add_to_process_id_name("test_cond0" )); |
256 | NamedCondition::remove(test::add_to_process_id_name("test_cond1" )); |
257 | NamedCondition::remove(test::add_to_process_id_name("named_condition" )); |
258 | NamedMutex::remove(test::add_to_process_id_name("named_mutex" )); |
259 | test::test_named_creation<test::named_condition_creation_test_wrapper_w<NamedCondition> >(); |
260 | #endif |
261 | test::do_test_condition<test::named_condition_test_wrapper<NamedCondition> |
262 | ,test::named_mutex_test_wrapper<NamedMutex> >(); |
263 | } |
264 | BOOST_CATCH(std::exception &ex){ |
265 | std::cout << ex.what() << std::endl; |
266 | ret = 1; |
267 | } BOOST_CATCH_END |
268 | NamedMutex::remove(test::add_to_process_id_name(name: "test_mutex0" )); |
269 | NamedCondition::remove(test::add_to_process_id_name(name: "test_cond0" )); |
270 | NamedCondition::remove(test::add_to_process_id_name(name: "test_cond1" )); |
271 | NamedCondition::remove(test::add_to_process_id_name(name: "named_condition" )); |
272 | NamedMutex::remove(test::add_to_process_id_name(name: "named_mutex" )); |
273 | return ret; |
274 | } |
275 | |
276 | }}} //namespace boost { namespace interprocess { namespace test { |
277 | |
278 | #include <boost/interprocess/detail/config_end.hpp> |
279 | |
280 | #endif //BOOST_INTERPROCESS_TEST_NAMED_CONDITION_HELPERS_HEADER |
281 | |