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_timed_locks test suite |
8 | |
9 | #include <boost/test/unit_test.hpp> |
10 | #include <boost/thread/thread_only.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 | |
22 | BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held) |
23 | { |
24 | boost::shared_mutex rw_mutex; |
25 | boost::mutex finish_mutex; |
26 | boost::mutex unblocked_mutex; |
27 | unsigned unblocked_count=0; |
28 | boost::unique_lock<boost::mutex> finish_lock(finish_mutex); |
29 | boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count)); |
30 | boost::thread::sleep(xt: delay(secs: 1)); |
31 | CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u); |
32 | |
33 | boost::system_time const start=boost::get_system_time(); |
34 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
35 | boost::posix_time::milliseconds const timeout_resolution(50); |
36 | bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout); |
37 | BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time()); |
38 | BOOST_CHECK(!timed_lock_succeeded); |
39 | if(timed_lock_succeeded) |
40 | { |
41 | rw_mutex.unlock_shared(); |
42 | } |
43 | |
44 | boost::posix_time::milliseconds const wait_duration(500); |
45 | boost::system_time const timeout2=boost::get_system_time()+wait_duration; |
46 | timed_lock_succeeded=rw_mutex.timed_lock_shared(relative_time: wait_duration); |
47 | BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time()); |
48 | BOOST_CHECK(!timed_lock_succeeded); |
49 | if(timed_lock_succeeded) |
50 | { |
51 | rw_mutex.unlock_shared(); |
52 | } |
53 | |
54 | finish_lock.unlock(); |
55 | writer.join(); |
56 | } |
57 | |
58 | BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held) |
59 | { |
60 | boost::shared_mutex rw_mutex; |
61 | boost::mutex finish_mutex; |
62 | boost::mutex unblocked_mutex; |
63 | |
64 | boost::system_time const start=boost::get_system_time(); |
65 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
66 | boost::posix_time::milliseconds const timeout_resolution(50); |
67 | bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout); |
68 | BOOST_CHECK(boost::get_system_time()<timeout); |
69 | BOOST_CHECK(timed_lock_succeeded); |
70 | if(timed_lock_succeeded) |
71 | { |
72 | rw_mutex.unlock_shared(); |
73 | } |
74 | |
75 | boost::posix_time::milliseconds const wait_duration(500); |
76 | boost::system_time const timeout2=boost::get_system_time()+wait_duration; |
77 | timed_lock_succeeded=rw_mutex.timed_lock_shared(relative_time: wait_duration); |
78 | BOOST_CHECK(boost::get_system_time()<timeout2); |
79 | BOOST_CHECK(timed_lock_succeeded); |
80 | if(timed_lock_succeeded) |
81 | { |
82 | rw_mutex.unlock_shared(); |
83 | } |
84 | |
85 | } |
86 | |
87 | BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held) |
88 | { |
89 | boost::shared_mutex rw_mutex; |
90 | boost::mutex finish_mutex; |
91 | boost::mutex unblocked_mutex; |
92 | unsigned unblocked_count=0; |
93 | boost::unique_lock<boost::mutex> finish_lock(finish_mutex); |
94 | boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count)); |
95 | boost::thread::sleep(xt: delay(secs: 1)); |
96 | CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u); |
97 | |
98 | boost::system_time const start=boost::get_system_time(); |
99 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
100 | boost::posix_time::milliseconds const timeout_resolution(50); |
101 | bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout); |
102 | BOOST_CHECK(boost::get_system_time()<timeout); |
103 | BOOST_CHECK(timed_lock_succeeded); |
104 | if(timed_lock_succeeded) |
105 | { |
106 | rw_mutex.unlock_shared(); |
107 | } |
108 | |
109 | boost::posix_time::milliseconds const wait_duration(500); |
110 | boost::system_time const timeout2=boost::get_system_time()+wait_duration; |
111 | timed_lock_succeeded=rw_mutex.timed_lock_shared(relative_time: wait_duration); |
112 | BOOST_CHECK(boost::get_system_time()<timeout2); |
113 | BOOST_CHECK(timed_lock_succeeded); |
114 | if(timed_lock_succeeded) |
115 | { |
116 | rw_mutex.unlock_shared(); |
117 | } |
118 | |
119 | finish_lock.unlock(); |
120 | reader.join(); |
121 | } |
122 | |
123 | BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_write_lock_held) |
124 | { |
125 | boost::shared_mutex rw_mutex; |
126 | boost::mutex finish_mutex; |
127 | boost::mutex unblocked_mutex; |
128 | unsigned unblocked_count=0; |
129 | boost::unique_lock<boost::mutex> finish_lock(finish_mutex); |
130 | boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count)); |
131 | boost::thread::sleep(xt: delay(secs: 1)); |
132 | CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u); |
133 | |
134 | boost::system_time const start=boost::get_system_time(); |
135 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
136 | boost::posix_time::milliseconds const timeout_resolution(50); |
137 | bool timed_lock_succeeded=rw_mutex.timed_lock(timeout); |
138 | BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time()); |
139 | BOOST_CHECK(!timed_lock_succeeded); |
140 | if(timed_lock_succeeded) |
141 | { |
142 | rw_mutex.unlock(); |
143 | } |
144 | |
145 | boost::posix_time::milliseconds const wait_duration(500); |
146 | boost::system_time const timeout2=boost::get_system_time()+wait_duration; |
147 | timed_lock_succeeded=rw_mutex.timed_lock(relative_time: wait_duration); |
148 | BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time()); |
149 | BOOST_CHECK(!timed_lock_succeeded); |
150 | if(timed_lock_succeeded) |
151 | { |
152 | rw_mutex.unlock(); |
153 | } |
154 | |
155 | finish_lock.unlock(); |
156 | writer.join(); |
157 | } |
158 | |
159 | BOOST_AUTO_TEST_CASE(test_timed_lock_succeeds_if_no_lock_held) |
160 | { |
161 | boost::shared_mutex rw_mutex; |
162 | boost::mutex finish_mutex; |
163 | boost::mutex unblocked_mutex; |
164 | |
165 | boost::system_time const start=boost::get_system_time(); |
166 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
167 | boost::posix_time::milliseconds const timeout_resolution(50); |
168 | bool timed_lock_succeeded=rw_mutex.timed_lock(timeout); |
169 | BOOST_CHECK(boost::get_system_time()<timeout); |
170 | BOOST_CHECK(timed_lock_succeeded); |
171 | if(timed_lock_succeeded) |
172 | { |
173 | rw_mutex.unlock(); |
174 | } |
175 | |
176 | boost::posix_time::milliseconds const wait_duration(500); |
177 | boost::system_time const timeout2=boost::get_system_time()+wait_duration; |
178 | timed_lock_succeeded=rw_mutex.timed_lock(relative_time: wait_duration); |
179 | BOOST_CHECK(boost::get_system_time()<timeout2); |
180 | BOOST_CHECK(timed_lock_succeeded); |
181 | if(timed_lock_succeeded) |
182 | { |
183 | rw_mutex.unlock(); |
184 | } |
185 | |
186 | } |
187 | |
188 | BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held) |
189 | { |
190 | boost::shared_mutex rw_mutex; |
191 | boost::mutex finish_mutex; |
192 | boost::mutex unblocked_mutex; |
193 | unsigned unblocked_count=0; |
194 | boost::unique_lock<boost::mutex> finish_lock(finish_mutex); |
195 | boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count)); |
196 | boost::thread::sleep(xt: delay(secs: 1)); |
197 | CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u); |
198 | |
199 | boost::system_time const start=boost::get_system_time(); |
200 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
201 | boost::posix_time::milliseconds const timeout_resolution(50); |
202 | bool timed_lock_succeeded=rw_mutex.timed_lock(timeout); |
203 | BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time()); |
204 | BOOST_CHECK(!timed_lock_succeeded); |
205 | if(timed_lock_succeeded) |
206 | { |
207 | rw_mutex.unlock(); |
208 | } |
209 | |
210 | boost::posix_time::milliseconds const wait_duration(500); |
211 | boost::system_time const timeout2=boost::get_system_time()+wait_duration; |
212 | timed_lock_succeeded=rw_mutex.timed_lock(relative_time: wait_duration); |
213 | BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time()); |
214 | BOOST_CHECK(!timed_lock_succeeded); |
215 | if(timed_lock_succeeded) |
216 | { |
217 | rw_mutex.unlock(); |
218 | } |
219 | |
220 | finish_lock.unlock(); |
221 | reader.join(); |
222 | } |
223 | |
224 | BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held) |
225 | { |
226 | boost::shared_mutex rw_mutex; |
227 | boost::mutex finish_mutex; |
228 | boost::mutex unblocked_mutex; |
229 | unsigned unblocked_count=0; |
230 | boost::unique_lock<boost::mutex> finish_lock(finish_mutex); |
231 | boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count)); |
232 | boost::this_thread::sleep(rel_time: boost::posix_time::seconds(1)); |
233 | CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u); |
234 | |
235 | boost::system_time const start=boost::get_system_time(); |
236 | boost::system_time const timeout=start+boost::posix_time::milliseconds(500); |
237 | bool timed_lock_succeeded=rw_mutex.timed_lock(timeout); |
238 | BOOST_CHECK(!timed_lock_succeeded); |
239 | if(timed_lock_succeeded) |
240 | { |
241 | rw_mutex.unlock(); |
242 | } |
243 | |
244 | boost::posix_time::milliseconds const wait_duration(500); |
245 | timed_lock_succeeded=rw_mutex.timed_lock_shared(relative_time: wait_duration); |
246 | BOOST_CHECK(timed_lock_succeeded); |
247 | if(timed_lock_succeeded) |
248 | { |
249 | rw_mutex.unlock_shared(); |
250 | } |
251 | |
252 | finish_lock.unlock(); |
253 | reader.join(); |
254 | } |
255 | |
256 | |