• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)24 BOOST_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(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(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)60 BOOST_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(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)88 BOOST_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(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(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_write_lock_held)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::this_thread::sleep_for(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(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_succeeds_if_no_lock_held)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::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(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)187 BOOST_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(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(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)223 BOOST_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(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(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(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