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 BOOST_INTERPROCESS_TEST_NAMED_CONDITION_HELPERS_HEADER
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
22namespace boost { namespace interprocess { namespace test {
23
24template<class NamedCondition>
25struct 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
40template<class NamedCondition>
41struct 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
57inline 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
62template<class NamedCondition>
63class 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
126template<class NamedCondition>
127int 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
131template<class NamedCondition>
132class 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
157template<class NamedCondition>
158int 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
164template<class NamedCondition>
165class 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
190template<class NamedCondition>
191int named_condition_creation_test_wrapper_w<NamedCondition>::count_ = 0;
192
193#endif //#if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES)
194
195template<class NamedMutex>
196struct 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
211template<class NamedMutex>
212class 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
236template<class NamedMutex>
237int named_mutex_test_wrapper<NamedMutex>::count = 0;
238
239template<class NamedCondition, class NamedMutex>
240int 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

source code of boost/libs/interprocess/test/named_condition_test_helpers.hpp