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_locks_chrono test suite
8
9#include <boost/test/unit_test.hpp>
10#include <boost/thread/thread.hpp>
11#include <boost/thread/shared_mutex.hpp>
12#include "./util.inl"
13#include "./shared_mutex_locking_thread.hpp"
14
15#if defined BOOST_THREAD_USES_CHRONO
16
17#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
18 { \
19 boost::unique_lock<boost::mutex> lock(mutex_name); \
20 BOOST_CHECK_EQUAL(value,expected_value); \
21 }
22
23
24BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)
25{
26 boost::shared_mutex rw_mutex;
27 boost::mutex finish_mutex;
28 boost::mutex unblocked_mutex;
29 unsigned unblocked_count=0;
30 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
31 boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
32 boost::this_thread::sleep_for(d: boost::chrono::seconds(1));
33 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
34
35 boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
36 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
37 boost::chrono::milliseconds const timeout_resolution(50);
38 bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(abs_time: timeout);
39 BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
40 BOOST_CHECK(!timed_lock_succeeded);
41 if(timed_lock_succeeded)
42 {
43 rw_mutex.unlock_shared();
44 }
45
46 boost::chrono::milliseconds const wait_duration(500);
47 boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
48 timed_lock_succeeded=rw_mutex.try_lock_shared_for(rel_time: wait_duration);
49 BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
50 BOOST_CHECK(!timed_lock_succeeded);
51 if(timed_lock_succeeded)
52 {
53 rw_mutex.unlock_shared();
54 }
55
56 finish_lock.unlock();
57 writer.join();
58}
59
60BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)
61{
62 boost::shared_mutex rw_mutex;
63 boost::mutex finish_mutex;
64 boost::mutex unblocked_mutex;
65
66 boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
67 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
68 bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(abs_time: timeout);
69 BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
70 BOOST_CHECK(timed_lock_succeeded);
71 if(timed_lock_succeeded)
72 {
73 rw_mutex.unlock_shared();
74 }
75
76 boost::chrono::milliseconds const wait_duration(500);
77 boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
78 timed_lock_succeeded=rw_mutex.try_lock_shared_for(rel_time: wait_duration);
79 BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
80 BOOST_CHECK(timed_lock_succeeded);
81 if(timed_lock_succeeded)
82 {
83 rw_mutex.unlock_shared();
84 }
85
86}
87
88BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)
89{
90 boost::shared_mutex rw_mutex;
91 boost::mutex finish_mutex;
92 boost::mutex unblocked_mutex;
93 unsigned unblocked_count=0;
94 boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
95 boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
96 boost::this_thread::sleep_for(d: boost::chrono::seconds(1));
97 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
98
99 boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
100 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
101 bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(abs_time: timeout);
102 BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
103 BOOST_CHECK(timed_lock_succeeded);
104 if(timed_lock_succeeded)
105 {
106 rw_mutex.unlock_shared();
107 }
108
109 boost::chrono::milliseconds const wait_duration(500);
110 boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
111 timed_lock_succeeded=rw_mutex.try_lock_shared_for(rel_time: wait_duration);
112 BOOST_CHECK(boost::chrono::steady_clock::now()<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::this_thread::sleep_for(d: boost::chrono::seconds(1));
132 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
133
134 boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
135 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
136 boost::chrono::milliseconds const timeout_resolution(50);
137 bool timed_lock_succeeded=rw_mutex.try_lock_until(abs_time: timeout);
138 BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
139 BOOST_CHECK(!timed_lock_succeeded);
140 if(timed_lock_succeeded)
141 {
142 rw_mutex.unlock();
143 }
144
145 boost::chrono::milliseconds const wait_duration(500);
146 boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
147 timed_lock_succeeded=rw_mutex.try_lock_for(rel_time: wait_duration);
148 BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
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::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
166 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
167 bool timed_lock_succeeded=rw_mutex.try_lock_until(abs_time: timeout);
168 BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
169 BOOST_CHECK(timed_lock_succeeded);
170 if(timed_lock_succeeded)
171 {
172 rw_mutex.unlock();
173 }
174
175 boost::chrono::milliseconds const wait_duration(500);
176 boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
177 timed_lock_succeeded=rw_mutex.try_lock_for(rel_time: wait_duration);
178 BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
179 BOOST_CHECK(timed_lock_succeeded);
180 if(timed_lock_succeeded)
181 {
182 rw_mutex.unlock();
183 }
184
185}
186
187BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)
188{
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::this_thread::sleep_for(d: boost::chrono::seconds(1));
196 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
197
198 boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
199 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
200 boost::chrono::milliseconds const timeout_resolution(50);
201 bool timed_lock_succeeded=rw_mutex.try_lock_until(abs_time: timeout);
202 BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
203 BOOST_CHECK(!timed_lock_succeeded);
204 if(timed_lock_succeeded)
205 {
206 rw_mutex.unlock();
207 }
208
209 boost::chrono::milliseconds const wait_duration(500);
210 boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
211 timed_lock_succeeded=rw_mutex.try_lock_for(rel_time: wait_duration);
212 BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
213 BOOST_CHECK(!timed_lock_succeeded);
214 if(timed_lock_succeeded)
215 {
216 rw_mutex.unlock();
217 }
218
219 finish_lock.unlock();
220 reader.join();
221}
222
223BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)
224{
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_for(d: boost::chrono::seconds(1));
232 CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
233
234 boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
235 boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
236 bool timed_lock_succeeded=rw_mutex.try_lock_until(abs_time: timeout);
237 BOOST_CHECK(!timed_lock_succeeded);
238 if(timed_lock_succeeded)
239 {
240 rw_mutex.unlock();
241 }
242
243 boost::chrono::milliseconds const wait_duration(500);
244 timed_lock_succeeded=rw_mutex.try_lock_shared_for(rel_time: wait_duration);
245 BOOST_CHECK(timed_lock_succeeded);
246 if(timed_lock_succeeded)
247 {
248 rw_mutex.unlock_shared();
249 }
250
251 finish_lock.unlock();
252 reader.join();
253}
254
255#else
256#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
257#endif
258
259
260

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