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)
6 #define BOOST_THREAD_VERSION 2
8 #include <boost/test/unit_test.hpp>
9 #include <boost/thread/thread_only.hpp>
10 #include <boost/thread/xtime.hpp>
12 #include "./shared_mutex_locking_thread.hpp"
14 #define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
16 boost::unique_lock<boost::mutex> lock(mutex_name); \
17 BOOST_CHECK_EQUAL(value,expected_value); \
21 void test_timed_lock_shared_times_out_if_write_lock_held()
23 boost::shared_mutex rw_mutex;
24 boost::mutex finish_mutex;
25 boost::mutex unblocked_mutex;
26 unsigned unblocked_count=0;
27 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
28 boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
29 boost::thread::sleep(delay(1));
30 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
32 boost::system_time const start=boost::get_system_time();
33 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
34 boost::posix_time::milliseconds const timeout_resolution(50);
35 bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
36 BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
37 BOOST_CHECK(!timed_lock_succeeded);
38 if(timed_lock_succeeded)
40 rw_mutex.unlock_shared();
43 boost::posix_time::milliseconds const wait_duration(500);
44 boost::system_time const timeout2=boost::get_system_time()+wait_duration;
45 timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
46 BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
47 BOOST_CHECK(!timed_lock_succeeded);
48 if(timed_lock_succeeded)
50 rw_mutex.unlock_shared();
57 void test_timed_lock_shared_succeeds_if_no_lock_held()
59 boost::shared_mutex rw_mutex;
60 boost::mutex finish_mutex;
61 boost::mutex unblocked_mutex;
63 boost::system_time const start=boost::get_system_time();
64 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
65 boost::posix_time::milliseconds const timeout_resolution(50);
66 bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
67 BOOST_CHECK(boost::get_system_time()<timeout);
68 BOOST_CHECK(timed_lock_succeeded);
69 if(timed_lock_succeeded)
71 rw_mutex.unlock_shared();
74 boost::posix_time::milliseconds const wait_duration(500);
75 boost::system_time const timeout2=boost::get_system_time()+wait_duration;
76 timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
77 BOOST_CHECK(boost::get_system_time()<timeout2);
78 BOOST_CHECK(timed_lock_succeeded);
79 if(timed_lock_succeeded)
81 rw_mutex.unlock_shared();
86 void test_timed_lock_shared_succeeds_if_read_lock_held()
88 boost::shared_mutex rw_mutex;
89 boost::mutex finish_mutex;
90 boost::mutex unblocked_mutex;
91 unsigned unblocked_count=0;
92 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
93 boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
94 boost::thread::sleep(delay(1));
95 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
97 boost::system_time const start=boost::get_system_time();
98 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
99 boost::posix_time::milliseconds const timeout_resolution(50);
100 bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
101 BOOST_CHECK(boost::get_system_time()<timeout);
102 BOOST_CHECK(timed_lock_succeeded);
103 if(timed_lock_succeeded)
105 rw_mutex.unlock_shared();
108 boost::posix_time::milliseconds const wait_duration(500);
109 boost::system_time const timeout2=boost::get_system_time()+wait_duration;
110 timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
111 BOOST_CHECK(boost::get_system_time()<timeout2);
112 BOOST_CHECK(timed_lock_succeeded);
113 if(timed_lock_succeeded)
115 rw_mutex.unlock_shared();
118 finish_lock.unlock();
122 void test_timed_lock_times_out_if_write_lock_held()
124 boost::shared_mutex rw_mutex;
125 boost::mutex finish_mutex;
126 boost::mutex unblocked_mutex;
127 unsigned unblocked_count=0;
128 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
129 boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
130 boost::thread::sleep(delay(1));
131 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
133 boost::system_time const start=boost::get_system_time();
134 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
135 boost::posix_time::milliseconds const timeout_resolution(50);
136 bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
137 BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
138 BOOST_CHECK(!timed_lock_succeeded);
139 if(timed_lock_succeeded)
144 boost::posix_time::milliseconds const wait_duration(500);
145 boost::system_time const timeout2=boost::get_system_time()+wait_duration;
146 timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
147 BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
148 BOOST_CHECK(!timed_lock_succeeded);
149 if(timed_lock_succeeded)
154 finish_lock.unlock();
158 void test_timed_lock_succeeds_if_no_lock_held()
160 boost::shared_mutex rw_mutex;
161 boost::mutex finish_mutex;
162 boost::mutex unblocked_mutex;
164 boost::system_time const start=boost::get_system_time();
165 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
166 boost::posix_time::milliseconds const timeout_resolution(50);
167 bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
168 BOOST_CHECK(boost::get_system_time()<timeout);
169 BOOST_CHECK(timed_lock_succeeded);
170 if(timed_lock_succeeded)
175 boost::posix_time::milliseconds const wait_duration(500);
176 boost::system_time const timeout2=boost::get_system_time()+wait_duration;
177 timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
178 BOOST_CHECK(boost::get_system_time()<timeout2);
179 BOOST_CHECK(timed_lock_succeeded);
180 if(timed_lock_succeeded)
187 void test_timed_lock_times_out_if_read_lock_held()
189 boost::shared_mutex rw_mutex;
190 boost::mutex finish_mutex;
191 boost::mutex unblocked_mutex;
192 unsigned unblocked_count=0;
193 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
194 boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
195 boost::thread::sleep(delay(1));
196 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
198 boost::system_time const start=boost::get_system_time();
199 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
200 boost::posix_time::milliseconds const timeout_resolution(50);
201 bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
202 BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
203 BOOST_CHECK(!timed_lock_succeeded);
204 if(timed_lock_succeeded)
209 boost::posix_time::milliseconds const wait_duration(500);
210 boost::system_time const timeout2=boost::get_system_time()+wait_duration;
211 timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
212 BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
213 BOOST_CHECK(!timed_lock_succeeded);
214 if(timed_lock_succeeded)
219 finish_lock.unlock();
223 void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
225 boost::shared_mutex rw_mutex;
226 boost::mutex finish_mutex;
227 boost::mutex unblocked_mutex;
228 unsigned unblocked_count=0;
229 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
230 boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
231 boost::this_thread::sleep(boost::posix_time::seconds(1));
232 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
234 boost::system_time const start=boost::get_system_time();
235 boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
236 bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
237 BOOST_CHECK(!timed_lock_succeeded);
238 if(timed_lock_succeeded)
243 boost::posix_time::milliseconds const wait_duration(500);
244 timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
245 BOOST_CHECK(timed_lock_succeeded);
246 if(timed_lock_succeeded)
248 rw_mutex.unlock_shared();
251 finish_lock.unlock();
256 boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
258 boost::unit_test::test_suite* test =
259 BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
261 test->add(BOOST_TEST_CASE(&test_timed_lock_shared_times_out_if_write_lock_held));
262 test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_no_lock_held));
263 test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_read_lock_held));
264 test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_write_lock_held));
265 test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_read_lock_held));
266 test->add(BOOST_TEST_CASE(&test_timed_lock_succeeds_if_no_lock_held));
267 test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held));