1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-2012. 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 #include <boost/interprocess/sync/named_mutex.hpp>
12 #include <boost/interprocess/sync/named_condition_any.hpp>
13 #include <boost/interprocess/sync/detail/locks.hpp>
14 #include "condition_test_template.hpp"
15 #include "named_creation_template.hpp"
16 #include <string>
17 #include <sstream>
18 #include "get_process_id_name.hpp"
19
20 using namespace boost::interprocess;
21
22 struct condition_deleter
23 {
24 std::string name;
25
~condition_deletercondition_deleter26 ~condition_deleter()
27 {
28 if(name.empty())
29 named_condition_any::remove(test::add_to_process_id_name("named_condition_any"));
30 else
31 named_condition_any::remove(name.c_str());
32 }
33 };
34
num_to_string(int n)35 inline std::string num_to_string(int n)
36 { std::stringstream s; s << n; return s.str(); }
37
38 //This wrapper is necessary to have a default constructor
39 //in generic mutex_test_template functions
40 class named_condition_any_test_wrapper
41 : public condition_deleter, public named_condition_any
42 {
43 public:
44
named_condition_any_test_wrapper()45 named_condition_any_test_wrapper()
46 : named_condition_any(open_or_create,
47 (test::add_to_process_id_name("test_cond") + num_to_string(count)).c_str())
48 {
49 condition_deleter::name += test::add_to_process_id_name("test_cond");
50 condition_deleter::name += num_to_string(count);
51 ++count;
52 }
53
~named_condition_any_test_wrapper()54 ~named_condition_any_test_wrapper()
55 { --count; }
56
57
58 template <typename L>
wait(L & lock)59 void wait(L& lock)
60 {
61 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
62 named_condition_any::wait(internal_lock);
63 }
64
65 template <typename L, typename Pr>
wait(L & lock,Pr pred)66 void wait(L& lock, Pr pred)
67 {
68 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
69 named_condition_any::wait(internal_lock, pred);
70 }
71
72 template <typename L>
timed_wait(L & lock,const boost::posix_time::ptime & abs_time)73 bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
74 {
75 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
76 return named_condition_any::timed_wait(internal_lock, abs_time);
77 }
78
79 template <typename L, typename Pr>
timed_wait(L & lock,const boost::posix_time::ptime & abs_time,Pr pred)80 bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
81 {
82 ipcdetail::internal_mutex_lock<L> internal_lock(lock);
83 return named_condition_any::timed_wait(internal_lock, abs_time, pred);
84 }
85
86 static int count;
87 };
88
89 int named_condition_any_test_wrapper::count = 0;
90
91 //This wrapper is necessary to have a common constructor
92 //in generic named_creation_template functions
93 class named_condition_any_creation_test_wrapper
94 : public condition_deleter, public named_condition_any
95 {
96 public:
named_condition_any_creation_test_wrapper(create_only_t)97 named_condition_any_creation_test_wrapper(create_only_t)
98 : named_condition_any(create_only, test::add_to_process_id_name("named_condition_any"))
99 { ++count_; }
100
named_condition_any_creation_test_wrapper(open_only_t)101 named_condition_any_creation_test_wrapper(open_only_t)
102 : named_condition_any(open_only, test::add_to_process_id_name("named_condition_any"))
103 { ++count_; }
104
named_condition_any_creation_test_wrapper(open_or_create_t)105 named_condition_any_creation_test_wrapper(open_or_create_t)
106 : named_condition_any(open_or_create, test::add_to_process_id_name("named_condition_any"))
107 { ++count_; }
108
~named_condition_any_creation_test_wrapper()109 ~named_condition_any_creation_test_wrapper() {
110 if(--count_){
111 ipcdetail::interprocess_tester::
112 dont_close_on_destruction(static_cast<named_condition_any&>(*this));
113 }
114 }
115 static int count_;
116 };
117
118 int named_condition_any_creation_test_wrapper::count_ = 0;
119
120 struct mutex_deleter
121 {
122 std::string name;
123
~mutex_deletermutex_deleter124 ~mutex_deleter()
125 {
126 if(name.empty())
127 named_mutex::remove(test::add_to_process_id_name("named_mutex"));
128 else
129 named_mutex::remove(name.c_str());
130 }
131 };
132
133 //This wrapper is necessary to have a default constructor
134 //in generic mutex_test_template functions
135 class named_mutex_test_wrapper
136 : public mutex_deleter, public named_mutex
137 {
138 public:
named_mutex_test_wrapper()139 named_mutex_test_wrapper()
140 : named_mutex(open_or_create,
141 (test::add_to_process_id_name("test_mutex") + num_to_string(count)).c_str())
142 {
143 mutex_deleter::name += test::add_to_process_id_name("test_mutex");
144 mutex_deleter::name += num_to_string(count);
145 ++count;
146 }
147
148 typedef named_mutex internal_mutex_type;
149
internal_mutex()150 internal_mutex_type &internal_mutex()
151 { return *this; }
152
~named_mutex_test_wrapper()153 ~named_mutex_test_wrapper()
154 { --count; }
155
156 static int count;
157 };
158
159 int named_mutex_test_wrapper::count = 0;
160
main()161 int main ()
162 {
163 try{
164 //Remove previous mutexes and conditions
165 named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
166 named_condition_any::remove(test::add_to_process_id_name("test_cond0"));
167 named_condition_any::remove(test::add_to_process_id_name("test_cond1"));
168 named_condition_any::remove(test::add_to_process_id_name("named_condition_any"));
169 named_mutex::remove(test::add_to_process_id_name("named_mutex"));
170
171 test::test_named_creation<named_condition_any_creation_test_wrapper>();
172 test::do_test_condition<named_condition_any_test_wrapper
173 ,named_mutex_test_wrapper>();
174 }
175 catch(std::exception &ex){
176 std::cout << ex.what() << std::endl;
177 return 1;
178 }
179 named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
180 named_condition_any::remove(test::add_to_process_id_name("test_cond0"));
181 named_condition_any::remove(test::add_to_process_id_name("test_cond1"));
182 named_condition_any::remove(test::add_to_process_id_name("named_condition_any"));
183 named_mutex::remove(test::add_to_process_id_name("named_mutex"));
184 return 0;
185 }
186
187