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
22BOOST_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
58BOOST_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
87BOOST_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
123BOOST_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
159BOOST_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
188BOOST_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
224BOOST_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

source code of boost/libs/thread/test/test_shared_mutex_timed_locks.cpp