]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2001-2003 |
2 | // William E. Kempf | |
3 | // Copyright (C) 2007 Anthony Williams | |
4 | // | |
5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #define BOOST_THREAD_VERSION 2 | |
9 | #define BOOST_THREAD_PROVIDES_INTERRUPTIONS | |
10 | #define BOOST_TEST_MODULE Boost.Threads: condition test suite | |
11 | #include <boost/thread/detail/config.hpp> | |
12 | ||
13 | #include <boost/thread/condition.hpp> | |
14 | #include <boost/thread/thread_only.hpp> | |
15 | #include <boost/thread/xtime.hpp> | |
16 | ||
f67539c2 | 17 | #include <boost/config.hpp> |
7c673cae FG |
18 | #include <boost/test/unit_test.hpp> |
19 | ||
20 | #include "./util.inl" | |
21 | ||
22 | struct condition_test_data | |
23 | { | |
24 | condition_test_data() : notified(0), awoken(0) { } | |
25 | ||
26 | boost::mutex mutex; | |
27 | boost::condition_variable condition; | |
28 | int notified; | |
29 | int awoken; | |
30 | }; | |
31 | ||
32 | void condition_test_thread(condition_test_data* data) | |
33 | { | |
34 | boost::unique_lock<boost::mutex> lock(data->mutex); | |
35 | BOOST_CHECK(lock ? true : false); | |
36 | while (!(data->notified > 0)) | |
37 | data->condition.wait(lock); | |
38 | BOOST_CHECK(lock ? true : false); | |
39 | data->awoken++; | |
40 | } | |
41 | ||
42 | struct cond_predicate | |
43 | { | |
44 | cond_predicate(int& var, int val) : _var(var), _val(val) { } | |
f67539c2 TL |
45 | #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) |
46 | cond_predicate(cond_predicate const&) = default; | |
47 | #endif | |
7c673cae FG |
48 | |
49 | bool operator()() { return _var == _val; } | |
50 | ||
51 | int& _var; | |
52 | int _val; | |
f67539c2 | 53 | |
7c673cae FG |
54 | private: |
55 | void operator=(cond_predicate&); | |
7c673cae FG |
56 | }; |
57 | ||
58 | void condition_test_waits(condition_test_data* data) | |
59 | { | |
60 | boost::unique_lock<boost::mutex> lock(data->mutex); | |
61 | BOOST_CHECK(lock ? true : false); | |
62 | ||
63 | // Test wait. | |
64 | while (data->notified != 1) | |
65 | data->condition.wait(lock); | |
66 | BOOST_CHECK(lock ? true : false); | |
67 | BOOST_CHECK_EQUAL(data->notified, 1); | |
68 | data->awoken++; | |
69 | data->condition.notify_one(); | |
70 | ||
71 | // Test predicate wait. | |
72 | data->condition.wait(lock, cond_predicate(data->notified, 2)); | |
73 | BOOST_CHECK(lock ? true : false); | |
74 | BOOST_CHECK_EQUAL(data->notified, 2); | |
75 | data->awoken++; | |
76 | data->condition.notify_one(); | |
77 | ||
78 | // Test timed_wait. | |
79 | boost::xtime xt = delay(10); | |
80 | while (data->notified != 3) | |
81 | data->condition.timed_wait(lock, xt); | |
82 | BOOST_CHECK(lock ? true : false); | |
83 | BOOST_CHECK_EQUAL(data->notified, 3); | |
84 | data->awoken++; | |
85 | data->condition.notify_one(); | |
86 | ||
87 | // Test predicate timed_wait. | |
88 | xt = delay(10); | |
89 | cond_predicate pred(data->notified, 4); | |
90 | BOOST_CHECK(data->condition.timed_wait(lock, xt, pred)); | |
91 | BOOST_CHECK(lock ? true : false); | |
92 | BOOST_CHECK(pred()); | |
93 | BOOST_CHECK_EQUAL(data->notified, 4); | |
94 | data->awoken++; | |
95 | data->condition.notify_one(); | |
96 | ||
97 | // Test predicate timed_wait with relative timeout | |
98 | cond_predicate pred_rel(data->notified, 5); | |
99 | BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel)); | |
100 | BOOST_CHECK(lock ? true : false); | |
101 | BOOST_CHECK(pred_rel()); | |
102 | BOOST_CHECK_EQUAL(data->notified, 5); | |
103 | data->awoken++; | |
104 | data->condition.notify_one(); | |
105 | } | |
106 | ||
107 | void do_test_condition_waits() | |
108 | { | |
109 | condition_test_data data; | |
110 | ||
111 | boost::thread thread(bind(&condition_test_waits, &data)); | |
112 | ||
113 | { | |
114 | boost::unique_lock<boost::mutex> lock(data.mutex); | |
115 | BOOST_CHECK(lock ? true : false); | |
116 | ||
117 | boost::thread::sleep(delay(1)); | |
118 | data.notified++; | |
119 | data.condition.notify_one(); | |
120 | while (data.awoken != 1) | |
121 | data.condition.wait(lock); | |
122 | BOOST_CHECK(lock ? true : false); | |
123 | BOOST_CHECK_EQUAL(data.awoken, 1); | |
124 | ||
125 | boost::thread::sleep(delay(1)); | |
126 | data.notified++; | |
127 | data.condition.notify_one(); | |
128 | while (data.awoken != 2) | |
129 | data.condition.wait(lock); | |
130 | BOOST_CHECK(lock ? true : false); | |
131 | BOOST_CHECK_EQUAL(data.awoken, 2); | |
132 | ||
133 | boost::thread::sleep(delay(1)); | |
134 | data.notified++; | |
135 | data.condition.notify_one(); | |
136 | while (data.awoken != 3) | |
137 | data.condition.wait(lock); | |
138 | BOOST_CHECK(lock ? true : false); | |
139 | BOOST_CHECK_EQUAL(data.awoken, 3); | |
140 | ||
141 | boost::thread::sleep(delay(1)); | |
142 | data.notified++; | |
143 | data.condition.notify_one(); | |
144 | while (data.awoken != 4) | |
145 | data.condition.wait(lock); | |
146 | BOOST_CHECK(lock ? true : false); | |
147 | BOOST_CHECK_EQUAL(data.awoken, 4); | |
148 | ||
149 | ||
150 | boost::thread::sleep(delay(1)); | |
151 | data.notified++; | |
152 | data.condition.notify_one(); | |
153 | while (data.awoken != 5) | |
154 | data.condition.wait(lock); | |
155 | BOOST_CHECK(lock ? true : false); | |
156 | BOOST_CHECK_EQUAL(data.awoken, 5); | |
157 | } | |
158 | ||
159 | thread.join(); | |
160 | BOOST_CHECK_EQUAL(data.awoken, 5); | |
161 | } | |
162 | ||
163 | BOOST_AUTO_TEST_CASE(test_condition_waits) | |
164 | { | |
165 | // We should have already tested notify_one here, so | |
166 | // a timed test with the default execution_monitor::use_condition | |
167 | // should be OK, and gives the fastest performance | |
168 | timed_test(&do_test_condition_waits, 12); | |
169 | } | |
170 | ||
171 | void do_test_condition_wait_is_a_interruption_point() | |
172 | { | |
173 | condition_test_data data; | |
174 | ||
175 | boost::thread thread(bind(&condition_test_thread, &data)); | |
176 | ||
177 | thread.interrupt(); | |
178 | thread.join(); | |
179 | BOOST_CHECK_EQUAL(data.awoken,0); | |
180 | } | |
181 | ||
182 | ||
183 | BOOST_AUTO_TEST_CASE(test_condition_wait_is_a_interruption_point) | |
184 | { | |
185 | timed_test(&do_test_condition_wait_is_a_interruption_point, 1); | |
186 | } | |
187 |