]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/thread/test/test_shared_mutex_part_2.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / thread / test / test_shared_mutex_part_2.cpp
1 // (C) Copyright 2006-7 Anthony Williams
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 #define BOOST_THREAD_VERSION 2
7 #define BOOST_TEST_MODULE Boost.Threads: shared_mutex_part2 test suite
8
9 #include <boost/test/unit_test.hpp>
10 #include <boost/thread/thread.hpp>
11 #include <boost/thread/xtime.hpp>
12 #include "./util.inl"
13 #include "./shared_mutex_locking_thread.hpp"
14
15 #define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
16 { \
17 boost::unique_lock<boost::mutex> lock(mutex_name); \
18 BOOST_CHECK_EQUAL(value,expected_value); \
19 }
20
21 class simple_upgrade_thread
22 {
23 boost::shared_mutex& rwm;
24 boost::mutex& finish_mutex;
25 boost::mutex& unblocked_mutex;
26 unsigned& unblocked_count;
27
28 void operator=(simple_upgrade_thread&);
29
30 public:
31 simple_upgrade_thread(boost::shared_mutex& rwm_,
32 boost::mutex& finish_mutex_,
33 boost::mutex& unblocked_mutex_,
34 unsigned& unblocked_count_):
35 rwm(rwm_),finish_mutex(finish_mutex_),
36 unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
37 {}
38
39 void operator()()
40 {
41 boost::upgrade_lock<boost::shared_mutex> lk(rwm);
42
43 {
44 boost::unique_lock<boost::mutex> ulk(unblocked_mutex);
45 ++unblocked_count;
46 }
47
48 boost::unique_lock<boost::mutex> flk(finish_mutex);
49 }
50 };
51
52
53 BOOST_AUTO_TEST_CASE(test_only_one_upgrade_lock_permitted)
54 {
55 unsigned const number_of_threads=2;
56
57 boost::thread_group pool;
58
59 boost::shared_mutex rw_mutex;
60 unsigned unblocked_count=0;
61 unsigned simultaneous_running_count=0;
62 unsigned max_simultaneous_running=0;
63 boost::mutex unblocked_count_mutex;
64 boost::condition_variable unblocked_condition;
65 boost::mutex finish_mutex;
66 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
67
68 try
69 {
70 for(unsigned i=0;i<number_of_threads;++i)
71 {
72 pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
73 finish_mutex,simultaneous_running_count,max_simultaneous_running));
74 }
75
76 boost::thread::sleep(delay(1));
77
78 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
79
80 finish_lock.unlock();
81
82 pool.join_all();
83 }
84 catch(...)
85 {
86 pool.interrupt_all();
87 pool.join_all();
88 throw;
89 }
90
91 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
92 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
93 }
94
95 BOOST_AUTO_TEST_CASE(test_can_lock_upgrade_if_currently_locked_shared)
96 {
97 boost::thread_group pool;
98
99 boost::shared_mutex rw_mutex;
100 unsigned unblocked_count=0;
101 unsigned simultaneous_running_count=0;
102 unsigned max_simultaneous_running=0;
103 boost::mutex unblocked_count_mutex;
104 boost::condition_variable unblocked_condition;
105 boost::mutex finish_mutex;
106 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
107
108 unsigned const reader_count=10;
109
110 try
111 {
112 for(unsigned i=0;i<reader_count;++i)
113 {
114 pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
115 finish_mutex,simultaneous_running_count,max_simultaneous_running));
116 }
117 boost::thread::sleep(delay(1));
118 pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
119 finish_mutex,simultaneous_running_count,max_simultaneous_running));
120 {
121 boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
122 while(unblocked_count<(reader_count+1))
123 {
124 unblocked_condition.wait(lk);
125 }
126 }
127 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
128
129 finish_lock.unlock();
130 pool.join_all();
131 }
132 catch(...)
133 {
134 pool.interrupt_all();
135 pool.join_all();
136 throw;
137 }
138
139
140 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
141 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
142 }
143
144 BOOST_AUTO_TEST_CASE(test_can_lock_upgrade_to_unique_if_currently_locked_upgrade)
145 {
146 boost::shared_mutex mtx;
147 boost::upgrade_lock<boost::shared_mutex> l(mtx);
148 boost::upgrade_to_unique_lock<boost::shared_mutex> ul(l);
149 BOOST_CHECK(ul.owns_lock());
150 }
151
152 BOOST_AUTO_TEST_CASE(test_if_other_thread_has_write_lock_try_lock_shared_returns_false)
153 {
154
155 boost::shared_mutex rw_mutex;
156 boost::mutex finish_mutex;
157 boost::mutex unblocked_mutex;
158 unsigned unblocked_count=0;
159 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
160 boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
161 boost::this_thread::sleep(boost::posix_time::seconds(1));
162 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
163
164 bool const try_succeeded=rw_mutex.try_lock_shared();
165 BOOST_CHECK(!try_succeeded);
166 if(try_succeeded)
167 {
168 rw_mutex.unlock_shared();
169 }
170
171 finish_lock.unlock();
172 writer.join();
173 }
174
175 BOOST_AUTO_TEST_CASE(test_if_other_thread_has_write_lock_try_lock_upgrade_returns_false)
176 {
177
178 boost::shared_mutex rw_mutex;
179 boost::mutex finish_mutex;
180 boost::mutex unblocked_mutex;
181 unsigned unblocked_count=0;
182 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
183 boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
184 boost::this_thread::sleep(boost::posix_time::seconds(1));
185 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
186
187 bool const try_succeeded=rw_mutex.try_lock_upgrade();
188 BOOST_CHECK(!try_succeeded);
189 if(try_succeeded)
190 {
191 rw_mutex.unlock_upgrade();
192 }
193
194 finish_lock.unlock();
195 writer.join();
196 }
197
198 BOOST_AUTO_TEST_CASE(test_if_no_thread_has_lock_try_lock_shared_returns_true)
199 {
200 boost::shared_mutex rw_mutex;
201 bool const try_succeeded=rw_mutex.try_lock_shared();
202 BOOST_CHECK(try_succeeded);
203 if(try_succeeded)
204 {
205 rw_mutex.unlock_shared();
206 }
207 }
208
209 BOOST_AUTO_TEST_CASE(test_if_no_thread_has_lock_try_lock_upgrade_returns_true)
210 {
211 boost::shared_mutex rw_mutex;
212 bool const try_succeeded=rw_mutex.try_lock_upgrade();
213 BOOST_CHECK(try_succeeded);
214 if(try_succeeded)
215 {
216 rw_mutex.unlock_upgrade();
217 }
218 }
219
220 BOOST_AUTO_TEST_CASE(test_if_other_thread_has_shared_lock_try_lock_shared_returns_true)
221 {
222
223 boost::shared_mutex rw_mutex;
224 boost::mutex finish_mutex;
225 boost::mutex unblocked_mutex;
226 unsigned unblocked_count=0;
227 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
228 boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
229 boost::thread::sleep(delay(1));
230 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
231
232 bool const try_succeeded=rw_mutex.try_lock_shared();
233 BOOST_CHECK(try_succeeded);
234 if(try_succeeded)
235 {
236 rw_mutex.unlock_shared();
237 }
238
239 finish_lock.unlock();
240 writer.join();
241 }
242
243 BOOST_AUTO_TEST_CASE(test_if_other_thread_has_shared_lock_try_lock_upgrade_returns_true)
244 {
245
246 boost::shared_mutex rw_mutex;
247 boost::mutex finish_mutex;
248 boost::mutex unblocked_mutex;
249 unsigned unblocked_count=0;
250 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
251 boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
252 boost::thread::sleep(delay(1));
253 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
254
255 bool const try_succeeded=rw_mutex.try_lock_upgrade();
256 BOOST_CHECK(try_succeeded);
257 if(try_succeeded)
258 {
259 rw_mutex.unlock_upgrade();
260 }
261
262 finish_lock.unlock();
263 writer.join();
264 }
265
266 BOOST_AUTO_TEST_CASE(test_if_other_thread_has_upgrade_lock_try_lock_upgrade_returns_false)
267 {
268
269 boost::shared_mutex rw_mutex;
270 boost::mutex finish_mutex;
271 boost::mutex unblocked_mutex;
272 unsigned unblocked_count=0;
273 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
274 boost::thread writer(simple_upgrade_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
275 boost::this_thread::sleep(boost::posix_time::seconds(1));
276 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
277
278 bool const try_succeeded=rw_mutex.try_lock_upgrade();
279 BOOST_CHECK(!try_succeeded);
280 if(try_succeeded)
281 {
282 rw_mutex.unlock_upgrade();
283 }
284
285 finish_lock.unlock();
286 writer.join();
287 }
288
289