]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/test/test_unbuffered_channel_post.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / test / test_unbuffered_channel_post.cpp
1
2 // Copyright Oliver Kowalke 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6
7 #include <chrono>
8 #include <sstream>
9 #include <string>
10 #include <vector>
11
12 #include <boost/assert.hpp>
13 #include <boost/test/unit_test.hpp>
14
15 #include <boost/fiber/all.hpp>
16
17 struct moveable {
18 bool state;
19 int value;
20
21 moveable() :
22 state( false),
23 value( -1) {
24 }
25
26 moveable( int v) :
27 state( true),
28 value( v) {
29 }
30
31 moveable( moveable && other) :
32 state( other.state),
33 value( other.value) {
34 other.state = false;
35 other.value = -1;
36 }
37
38 moveable & operator=( moveable && other) {
39 if ( this == & other) return * this;
40 state = other.state;
41 other.state = false;
42 value = other.value;
43 other.value = -1;
44 return * this;
45 }
46 };
47
48 void test_push() {
49 boost::fibers::unbuffered_channel< int > c;
50 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
51 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
52 });
53 int value = 0;
54 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
55 BOOST_CHECK_EQUAL( 1, value);
56 f.join();
57 }
58
59 void test_push_closed() {
60 boost::fibers::unbuffered_channel< int > c;
61 c.close();
62 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push( 1) );
63 }
64
65
66 void test_push_wait_for() {
67 boost::fibers::unbuffered_channel< int > c;
68 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
69 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
70 });
71 int value = 0;
72 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
73 BOOST_CHECK_EQUAL( 1, value);
74 f.join();
75 }
76
77 void test_push_wait_for_closed() {
78 boost::fibers::unbuffered_channel< int > c;
79 c.close();
80 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
81 }
82
83 void test_push_wait_for_timeout() {
84 boost::fibers::unbuffered_channel< int > c;
85 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
86 int value = 0;
87 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
88 BOOST_CHECK_EQUAL( 1, value);
89 });
90 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
91 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
92 f.join();
93 }
94
95 void test_push_wait_until() {
96 boost::fibers::unbuffered_channel< int > c;
97 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
98 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_until( 1,
99 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
100 });
101 int value = 0;
102 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
103 BOOST_CHECK_EQUAL( 1, value);
104 f.join();
105 }
106
107 void test_push_wait_until_closed() {
108 boost::fibers::unbuffered_channel< int > c;
109 c.close();
110 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push_wait_until( 1,
111 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
112 }
113
114 void test_push_wait_until_timeout() {
115 boost::fibers::unbuffered_channel< int > c;
116 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
117 int value = 0;
118 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
119 BOOST_CHECK_EQUAL( 1, value);
120 });
121 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_until( 1,
122 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
123 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.push_wait_until( 1,
124 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
125 f.join();
126 }
127
128 void test_pop() {
129 boost::fibers::unbuffered_channel< int > c;
130 int v1 = 2, v2 = 0;
131 boost::fibers::fiber f( boost::fibers::launch::post, [&v1,&c](){
132 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
133 });
134 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
135 BOOST_CHECK_EQUAL( v1, v2);
136 f.join();
137 }
138
139 void test_pop_closed() {
140 boost::fibers::unbuffered_channel< int > c;
141 int v1 = 2, v2 = 0;
142 boost::fibers::fiber f( boost::fibers::launch::post, [&v1,&c](){
143 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
144 c.close();
145 });
146 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
147 BOOST_CHECK_EQUAL( v1, v2);
148 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop( v2) );
149 f.join();
150 }
151
152 void test_pop_success() {
153 boost::fibers::unbuffered_channel< int > c;
154 int v1 = 2, v2 = 0;
155 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
156 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
157 });
158 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
159 f.join();
160 BOOST_CHECK_EQUAL( v1, v2);
161 }
162
163 void test_value_pop() {
164 boost::fibers::unbuffered_channel< int > c;
165 int v1 = 2, v2 = 0;
166 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
167 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
168 });
169 v2 = c.value_pop();
170 f.join();
171 BOOST_CHECK_EQUAL( v1, v2);
172 }
173
174 void test_value_pop_closed() {
175 boost::fibers::unbuffered_channel< int > c;
176 int v1 = 2;
177 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
178 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
179 c.close();
180 });
181 int v2 = c.value_pop();
182 BOOST_CHECK_EQUAL( v1, v2);
183 f.join();
184 bool thrown = false;
185 try {
186 c.value_pop();
187 } catch ( boost::fibers::fiber_error const&) {
188 thrown = true;
189 }
190 BOOST_CHECK( thrown);
191 }
192
193 void test_value_pop_success() {
194 boost::fibers::unbuffered_channel< int > c;
195 int v1 = 2, v2 = 0;
196 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
197 v2 = c.value_pop();
198 });
199 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
200 f.join();
201 BOOST_CHECK_EQUAL( v1, v2);
202 }
203
204 void test_pop_wait_for() {
205 boost::fibers::unbuffered_channel< int > c;
206 int v1 = 2, v2 = 0;
207 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
208 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
209 });
210 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
211 f.join();
212 BOOST_CHECK_EQUAL( v1, v2);
213 }
214
215 void test_pop_wait_for_closed() {
216 boost::fibers::unbuffered_channel< int > c;
217 int v1 = 2, v2 = 0;
218 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
219 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
220 c.close();
221 });
222 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
223 BOOST_CHECK_EQUAL( v1, v2);
224 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
225 f.join();
226 }
227
228 void test_pop_wait_for_success() {
229 boost::fibers::unbuffered_channel< int > c;
230 int v1 = 2, v2 = 0;
231 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
232 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
233 });
234 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
235 f.join();
236 BOOST_CHECK_EQUAL( v1, v2);
237 }
238
239 void test_pop_wait_for_timeout() {
240 boost::fibers::unbuffered_channel< int > c;
241 int v = 0;
242 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v](){
243 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.pop_wait_for( v, std::chrono::seconds( 1) ) );
244 });
245 f.join();
246 }
247
248 void test_pop_wait_until() {
249 boost::fibers::unbuffered_channel< int > c;
250 int v1 = 2, v2 = 0;
251 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
252 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
253 });
254 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
255 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
256 BOOST_CHECK_EQUAL( v1, v2);
257 f.join();
258 }
259
260 void test_pop_wait_until_closed() {
261 boost::fibers::unbuffered_channel< int > c;
262 int v1 = 2, v2 = 0;
263 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
264 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
265 c.close();
266 });
267 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
268 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
269 BOOST_CHECK_EQUAL( v1, v2);
270 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_until( v2,
271 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
272 f.join();
273 }
274
275 void test_pop_wait_until_success() {
276 boost::fibers::unbuffered_channel< int > c;
277 int v1 = 2, v2 = 0;
278 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
279 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
280 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
281 });
282 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
283 f.join();
284 BOOST_CHECK_EQUAL( v1, v2);
285 }
286
287 void test_pop_wait_until_timeout() {
288 boost::fibers::unbuffered_channel< int > c;
289 int v = 0;
290 BOOST_CHECK(
291 boost::fibers::channel_op_status::timeout == c.pop_wait_until( v,
292 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
293 }
294
295 void test_wm_1() {
296 boost::fibers::unbuffered_channel< int > c;
297 std::vector< boost::fibers::fiber::id > ids;
298 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&ids](){
299 ids.push_back( boost::this_fiber::get_id() );
300 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
301
302 ids.push_back( boost::this_fiber::get_id() );
303 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 2) );
304
305 ids.push_back( boost::this_fiber::get_id() );
306 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 3) );
307
308 ids.push_back( boost::this_fiber::get_id() );
309 // would be blocked because channel is full
310 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 4) );
311
312 ids.push_back( boost::this_fiber::get_id() );
313 // would be blocked because channel is full
314 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 5) );
315
316 ids.push_back( boost::this_fiber::get_id() );
317 });
318 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,&ids](){
319 ids.push_back( boost::this_fiber::get_id() );
320 BOOST_CHECK_EQUAL( 1, c.value_pop() );
321
322 // let other fiber run
323 boost::this_fiber::yield();
324
325 ids.push_back( boost::this_fiber::get_id() );
326 BOOST_CHECK_EQUAL( 2, c.value_pop() );
327
328 ids.push_back( boost::this_fiber::get_id() );
329 BOOST_CHECK_EQUAL( 3, c.value_pop() );
330
331 ids.push_back( boost::this_fiber::get_id() );
332 BOOST_CHECK_EQUAL( 4, c.value_pop() );
333
334 ids.push_back( boost::this_fiber::get_id() );
335 // would block because channel is empty
336 BOOST_CHECK_EQUAL( 5, c.value_pop() );
337
338 ids.push_back( boost::this_fiber::get_id() );
339 });
340 boost::fibers::fiber::id id1 = f1.get_id();
341 boost::fibers::fiber::id id2 = f2.get_id();
342 f1.join();
343 f2.join();
344 BOOST_CHECK_EQUAL( 12u, ids.size() );
345 BOOST_CHECK_EQUAL( id1, ids[0]);
346 BOOST_CHECK_EQUAL( id2, ids[1]);
347 BOOST_CHECK_EQUAL( id1, ids[2]);
348 BOOST_CHECK_EQUAL( id2, ids[3]);
349 BOOST_CHECK_EQUAL( id2, ids[4]);
350 BOOST_CHECK_EQUAL( id1, ids[5]);
351 BOOST_CHECK_EQUAL( id2, ids[6]);
352 BOOST_CHECK_EQUAL( id1, ids[7]);
353 BOOST_CHECK_EQUAL( id2, ids[8]);
354 BOOST_CHECK_EQUAL( id1, ids[9]);
355 BOOST_CHECK_EQUAL( id2, ids[10]);
356 BOOST_CHECK_EQUAL( id1, ids[11]);
357 }
358
359 void test_moveable() {
360 boost::fibers::unbuffered_channel< moveable > c;
361 boost::fibers::fiber f( boost::fibers::launch::post, [&c]{
362 moveable m1( 3);
363 BOOST_CHECK( m1.state);
364 BOOST_CHECK_EQUAL( 3, m1.value);
365 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( std::move( m1) ) );
366 });
367 moveable m2;
368 BOOST_CHECK( ! m2.state);
369 BOOST_CHECK_EQUAL( -1, m2.value);
370 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( m2) );
371 BOOST_CHECK( m2.state);
372 BOOST_CHECK_EQUAL( 3, m2.value);
373 f.join();
374 }
375
376 void test_rangefor() {
377 boost::fibers::unbuffered_channel< int > chan;
378 std::vector< int > vec;
379 boost::fibers::fiber f1( boost::fibers::launch::post, [&chan]{
380 chan.push( 1);
381 chan.push( 1);
382 chan.push( 2);
383 chan.push( 3);
384 chan.push( 5);
385 chan.push( 8);
386 chan.push( 12);
387 chan.close();
388 });
389 boost::fibers::fiber f2( boost::fibers::launch::post, [&vec,&chan]{
390 for ( int value : chan) {
391 vec.push_back( value);
392 }
393 });
394 f1.join();
395 f2.join();
396 BOOST_CHECK_EQUAL( 1, vec[0]);
397 BOOST_CHECK_EQUAL( 1, vec[1]);
398 BOOST_CHECK_EQUAL( 2, vec[2]);
399 BOOST_CHECK_EQUAL( 3, vec[3]);
400 BOOST_CHECK_EQUAL( 5, vec[4]);
401 BOOST_CHECK_EQUAL( 8, vec[5]);
402 BOOST_CHECK_EQUAL( 12, vec[6]);
403 }
404
405 boost::unit_test::test_suite * init_unit_test_suite( int, char* []) {
406 boost::unit_test::test_suite * test =
407 BOOST_TEST_SUITE("Boost.Fiber: unbuffered_channel test suite");
408
409 test->add( BOOST_TEST_CASE( & test_push) );
410 test->add( BOOST_TEST_CASE( & test_push_closed) );
411 test->add( BOOST_TEST_CASE( & test_push_wait_for) );
412 test->add( BOOST_TEST_CASE( & test_push_wait_for_closed) );
413 test->add( BOOST_TEST_CASE( & test_push_wait_for_timeout) );
414 test->add( BOOST_TEST_CASE( & test_push_wait_until) );
415 test->add( BOOST_TEST_CASE( & test_push_wait_until_closed) );
416 test->add( BOOST_TEST_CASE( & test_push_wait_until_timeout) );
417 test->add( BOOST_TEST_CASE( & test_pop) );
418 test->add( BOOST_TEST_CASE( & test_pop_closed) );
419 test->add( BOOST_TEST_CASE( & test_pop_success) );
420 test->add( BOOST_TEST_CASE( & test_value_pop) );
421 test->add( BOOST_TEST_CASE( & test_value_pop_closed) );
422 test->add( BOOST_TEST_CASE( & test_value_pop_success) );
423 test->add( BOOST_TEST_CASE( & test_pop_wait_for) );
424 test->add( BOOST_TEST_CASE( & test_pop_wait_for_closed) );
425 test->add( BOOST_TEST_CASE( & test_pop_wait_for_success) );
426 test->add( BOOST_TEST_CASE( & test_pop_wait_for_timeout) );
427 test->add( BOOST_TEST_CASE( & test_pop_wait_until) );
428 test->add( BOOST_TEST_CASE( & test_pop_wait_until_closed) );
429 test->add( BOOST_TEST_CASE( & test_pop_wait_until_success) );
430 test->add( BOOST_TEST_CASE( & test_pop_wait_until_timeout) );
431 test->add( BOOST_TEST_CASE( & test_wm_1) );
432 test->add( BOOST_TEST_CASE( & test_moveable) );
433 test->add( BOOST_TEST_CASE( & test_rangefor) );
434
435 return test;
436 }