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