• 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_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 
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)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(delay(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)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(delay(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(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 
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::thread::sleep(delay(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(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 
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::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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)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(delay(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(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 
BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)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(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(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