]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/test/test_bounded_channel_post.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / test / test_bounded_channel_post.cpp
CommitLineData
7c673cae
FG
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
17struct 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
48void test_zero_wm_1() {
49 bool thrown = false;
50 try {
51 boost::fibers::bounded_channel< int > c( 0);
52 } catch ( boost::fibers::fiber_error const&) {
53 thrown = true;
54 }
55 BOOST_CHECK( thrown);
56}
57
58void test_zero_wm_2() {
59 bool thrown = false;
60 try {
61 boost::fibers::bounded_channel< int > c( 0, 0);
62 } catch ( boost::fibers::fiber_error const&) {
63 thrown = true;
64 }
65 BOOST_CHECK( thrown);
66}
67
68void test_hwm_less_lwm() {
69 bool thrown = false;
70 try {
71 boost::fibers::bounded_channel< int > c( 2, 3);
72 } catch ( boost::fibers::fiber_error const&) {
73 thrown = true;
74 }
75 BOOST_CHECK( thrown);
76}
77
78void test_hwm_equal_lwm() {
79 bool thrown = false;
80 try {
81 boost::fibers::bounded_channel< int > c( 3, 3);
82 } catch ( boost::fibers::fiber_error const&) {
83 thrown = true;
84 }
85 BOOST_CHECK( thrown);
86}
87
88void test_push() {
89 boost::fibers::bounded_channel< int > c( 10);
90 BOOST_CHECK_EQUAL( c.upper_bound(), 10u );
91 BOOST_CHECK_EQUAL( c.lower_bound(), 9u );
92 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
93}
94
95void test_push_closed() {
96 boost::fibers::bounded_channel< int > c( 10);
97 c.close();
98 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push( 1) );
99}
100
101void test_try_push() {
102 boost::fibers::bounded_channel< int > c( 1);
103 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
104}
105
106void test_try_push_closed() {
107 boost::fibers::bounded_channel< int > c( 1);
108 BOOST_CHECK( boost::fibers::channel_op_status::success == c.try_push( 1) );
109 c.close();
110 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.try_push( 2) );
111}
112
113void test_try_push_full() {
114 boost::fibers::bounded_channel< int > c( 1);
115 BOOST_CHECK_EQUAL( c.lower_bound(), 0u );
116 BOOST_CHECK( boost::fibers::channel_op_status::success == c.try_push( 1) );
117 BOOST_CHECK( boost::fibers::channel_op_status::full == c.try_push( 2) );
118}
119
120void test_push_wait_for() {
121 boost::fibers::bounded_channel< int > c( 2);
122 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
123}
124
125void test_push_wait_for_closed() {
126 boost::fibers::bounded_channel< int > c( 1);
127 c.close();
128 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
129}
130
131void test_push_wait_for_timeout() {
132 boost::fibers::bounded_channel< int > c( 1);
133 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
134 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
135}
136
137void test_push_wait_until() {
138 boost::fibers::bounded_channel< int > c( 2);
139 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_until( 1,
140 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
141}
142
143void test_push_wait_until_closed() {
144 boost::fibers::bounded_channel< int > c( 1);
145 c.close();
146 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push_wait_until( 1,
147 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
148}
149
150void test_push_wait_until_timeout() {
151 boost::fibers::bounded_channel< int > c( 1);
152 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_until( 1,
153 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
154 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.push_wait_until( 1,
155 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
156}
157
158void test_pop() {
159 boost::fibers::bounded_channel< int > c( 10);
160 int v1 = 2, v2 = 0;
161 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
162 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
163 BOOST_CHECK_EQUAL( v1, v2);
164}
165
166void test_pop_closed() {
167 boost::fibers::bounded_channel< int > c( 10);
168 int v1 = 2, v2 = 0;
169 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
170 c.close();
171 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
172 BOOST_CHECK_EQUAL( v1, v2);
173 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop( v2) );
174}
175
176void test_pop_success() {
177 boost::fibers::bounded_channel< int > c( 10);
178 int v1 = 2, v2 = 0;
179 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){
180 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
181 });
182 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){
183 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
184 });
185 f1.join();
186 f2.join();
187 BOOST_CHECK_EQUAL( v1, v2);
188}
189
190void test_value_pop() {
191 boost::fibers::bounded_channel< int > c( 10);
192 int v1 = 2, v2 = 0;
193 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
194 v2 = c.value_pop();
195 BOOST_CHECK_EQUAL( v1, v2);
196}
197
198void test_value_pop_closed() {
199 boost::fibers::bounded_channel< int > c( 10);
200 int v1 = 2, v2 = 0;
201 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
202 c.close();
203 v2 = c.value_pop();
204 BOOST_CHECK_EQUAL( v1, v2);
205 bool thrown = false;
206 try {
207 c.value_pop();
208 } catch ( boost::fibers::fiber_error const&) {
209 thrown = true;
210 }
211 BOOST_CHECK( thrown);
212}
213
214void test_value_pop_success() {
215 boost::fibers::bounded_channel< int > c( 10);
216 int v1 = 2, v2 = 0;
217 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){
218 v2 = c.value_pop();
219 });
220 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){
221 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
222 });
223 f1.join();
224 f2.join();
225 BOOST_CHECK_EQUAL( v1, v2);
226}
227
228void test_try_pop() {
229 boost::fibers::bounded_channel< int > c( 10);
230 int v1 = 2, v2 = 0;
231 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
232 BOOST_CHECK( boost::fibers::channel_op_status::success == c.try_pop( v2) );
233 BOOST_CHECK_EQUAL( v1, v2);
234}
235
236void test_try_pop_closed() {
237 boost::fibers::bounded_channel< int > c( 10);
238 int v1 = 2, v2 = 0;
239 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
240 c.close();
241 BOOST_CHECK( boost::fibers::channel_op_status::success == c.try_pop( v2) );
242 BOOST_CHECK_EQUAL( v1, v2);
243 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.try_pop( v2) );
244}
245
246void test_try_pop_success() {
247 boost::fibers::bounded_channel< int > c( 10);
248 int v1 = 2, v2 = 0;
249 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){
250 while ( boost::fibers::channel_op_status::success != c.try_pop( v2) );
251 });
252 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){
253 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
254 });
255 f1.join();
256 f2.join();
257 BOOST_CHECK_EQUAL( v1, v2);
258}
259
260void test_pop_wait_for() {
261 boost::fibers::bounded_channel< int > c( 10);
262 int v1 = 2, v2 = 0;
263 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
264 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
265 BOOST_CHECK_EQUAL( v1, v2);
266}
267
268void test_pop_wait_for_closed() {
269 boost::fibers::bounded_channel< int > c( 10);
270 int v1 = 2, v2 = 0;
271 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
272 c.close();
273 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
274 BOOST_CHECK_EQUAL( v1, v2);
275 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
276}
277
278void test_pop_wait_for_success() {
279 boost::fibers::bounded_channel< int > c( 10);
280 int v1 = 2, v2 = 0;
281 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){
282 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
283 });
284 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){
285 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
286 });
287 f1.join();
288 f2.join();
289 BOOST_CHECK_EQUAL( v1, v2);
290}
291
292void test_pop_wait_for_timeout() {
293 boost::fibers::bounded_channel< int > c( 10);
294 int v = 0;
295 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v](){
296 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.pop_wait_for( v, std::chrono::seconds( 1) ) );
297 });
298 f.join();
299}
300
301void test_pop_wait_until() {
302 boost::fibers::bounded_channel< int > c( 10);
303 int v1 = 2, v2 = 0;
304 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
305 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
306 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
307 BOOST_CHECK_EQUAL( v1, v2);
308}
309
310void test_pop_wait_until_closed() {
311 boost::fibers::bounded_channel< int > c( 10);
312 int v1 = 2, v2 = 0;
313 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
314 c.close();
315 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
316 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
317 BOOST_CHECK_EQUAL( v1, v2);
318 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_until( v2,
319 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
320}
321
322void test_pop_wait_until_success() {
323 boost::fibers::bounded_channel< int > c( 10);
324 int v1 = 2, v2 = 0;
325 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&v2](){
326 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
327 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
328 });
329 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,v1](){
330 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
331 });
332 f1.join();
333 f2.join();
334 BOOST_CHECK_EQUAL( v1, v2);
335}
336
337void test_pop_wait_until_timeout() {
338 boost::fibers::bounded_channel< int > c( 10);
339 int v = 0;
340 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v](){
341 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.pop_wait_until( v,
342 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
343 });
344 f.join();
345}
346
347void test_wm_1() {
348 boost::fibers::bounded_channel< int > c( 3);
349 std::vector< boost::fibers::fiber::id > ids;
350 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&ids](){
351 ids.push_back( boost::this_fiber::get_id() );
352 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
353
354 ids.push_back( boost::this_fiber::get_id() );
355 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 2) );
356
357 ids.push_back( boost::this_fiber::get_id() );
358 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 3) );
359
360 ids.push_back( boost::this_fiber::get_id() );
361 // would be blocked because channel is full
362 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 4) );
363
364 ids.push_back( boost::this_fiber::get_id() );
365 // would be blocked because channel is full
366 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 5) );
367
368 ids.push_back( boost::this_fiber::get_id() );
369 });
370 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,&ids](){
371 ids.push_back( boost::this_fiber::get_id() );
372 BOOST_CHECK_EQUAL( 1, c.value_pop() );
373
374 // let other fiber run
375 boost::this_fiber::yield();
376
377 ids.push_back( boost::this_fiber::get_id() );
378 BOOST_CHECK_EQUAL( 2, c.value_pop() );
379
380 ids.push_back( boost::this_fiber::get_id() );
381 BOOST_CHECK_EQUAL( 3, c.value_pop() );
382
383 ids.push_back( boost::this_fiber::get_id() );
384 BOOST_CHECK_EQUAL( 4, c.value_pop() );
385
386 ids.push_back( boost::this_fiber::get_id() );
387 // would block because channel is empty
388 BOOST_CHECK_EQUAL( 5, c.value_pop() );
389
390 ids.push_back( boost::this_fiber::get_id() );
391 });
392 boost::fibers::fiber::id id1 = f1.get_id();
393 boost::fibers::fiber::id id2 = f2.get_id();
394 f1.join();
395 f2.join();
396 BOOST_CHECK_EQUAL( 12u, ids.size() );
397 BOOST_CHECK_EQUAL( id1, ids[0]); // f1 pushes 1
398 BOOST_CHECK_EQUAL( id1, ids[1]); // f1 pushes 2
399 BOOST_CHECK_EQUAL( id1, ids[2]); // f1 pushes 3
400 BOOST_CHECK_EQUAL( id1, ids[3]); // f1 blocks in push( 4) (channel is full)
401 BOOST_CHECK_EQUAL( id2, ids[4]); // f2 resumes and pops 1, f1 gets ready to push 4, f2 yields
402 BOOST_CHECK_EQUAL( id1, ids[5]); // f1 resumes and pushes 4, blocks in push( 5) (channel full)
403 BOOST_CHECK_EQUAL( id2, ids[6]); // f2 resumes and pops 2
404 BOOST_CHECK_EQUAL( id2, ids[7]); // f2 pops 3
405 BOOST_CHECK_EQUAL( id2, ids[8]); // f2 pops 4
406 BOOST_CHECK_EQUAL( id2, ids[9]); // f2 blocks in pop() (channel is empty)
407 BOOST_CHECK_EQUAL( id1, ids[10]); // f1 resumes and pushes 4, completes
408 BOOST_CHECK_EQUAL( id2, ids[11]); // f2 resumes and pops 5, completes
409}
410
411void test_wm_2() {
412 boost::fibers::bounded_channel< int > c( 3);
413 std::vector< boost::fibers::fiber::id > ids;
414 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&ids](){
415 ids.push_back( boost::this_fiber::get_id() );
416 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
417
418 ids.push_back( boost::this_fiber::get_id() );
419 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 2) );
420
421 ids.push_back( boost::this_fiber::get_id() );
422 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 3) );
423
424 ids.push_back( boost::this_fiber::get_id() );
425 // would be blocked because channel is full
426 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 4) );
427
428 ids.push_back( boost::this_fiber::get_id() );
429 // would be blocked because channel is full
430 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 5) );
431
432 ids.push_back( boost::this_fiber::get_id() );
433 });
434 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,&ids](){
435 ids.push_back( boost::this_fiber::get_id() );
436 BOOST_CHECK_EQUAL( 1, c.value_pop() );
437
438 // let other fiber run
439 boost::this_fiber::yield();
440
441 ids.push_back( boost::this_fiber::get_id() );
442 BOOST_CHECK_EQUAL( 2, c.value_pop() );
443
444 // let other fiber run
445 boost::this_fiber::yield();
446
447 ids.push_back( boost::this_fiber::get_id() );
448 BOOST_CHECK_EQUAL( 3, c.value_pop() );
449
450 ids.push_back( boost::this_fiber::get_id() );
451 BOOST_CHECK_EQUAL( 4, c.value_pop() );
452
453 ids.push_back( boost::this_fiber::get_id() );
454 BOOST_CHECK_EQUAL( 5, c.value_pop() );
455
456 ids.push_back( boost::this_fiber::get_id() );
457 });
458 boost::fibers::fiber::id id1 = f1.get_id();
459 boost::fibers::fiber::id id2 = f2.get_id();
460 f1.join();
461 f2.join();
462 BOOST_CHECK_EQUAL( 12u, ids.size() );
463 BOOST_CHECK_EQUAL( id1, ids[0]); // f1 pushes 1
464 BOOST_CHECK_EQUAL( id1, ids[1]); // f1 pushes 2
465 BOOST_CHECK_EQUAL( id1, ids[2]); // f1 pushes 3
466 BOOST_CHECK_EQUAL( id1, ids[3]); // f1 blocks in push( 4) (channel is full)
467 BOOST_CHECK_EQUAL( id2, ids[4]); // f2 resumes and pops 1, f1 gets ready to push 4, f2 yields
468 BOOST_CHECK_EQUAL( id1, ids[5]); // f1 resumes and pushes 4, blocks in push( 5) (channel full)
469 BOOST_CHECK_EQUAL( id2, ids[6]); // f2 resumes and pops 2, f1 gets ready tp push 5, f2 yields
470 BOOST_CHECK_EQUAL( id1, ids[7]); // f1 resumes and pushes 5, completes
471 BOOST_CHECK_EQUAL( id2, ids[8]); // f2 resumes and pops 3
472 BOOST_CHECK_EQUAL( id2, ids[9]); // f2 pops 4
473 BOOST_CHECK_EQUAL( id2, ids[10]); // f2 pops 5
474 BOOST_CHECK_EQUAL( id2, ids[11]); // f2 completes
475}
476
477void test_wm_3() {
478 boost::fibers::bounded_channel< int > c( 3, 1);
479 BOOST_CHECK_EQUAL( c.upper_bound(), 3u );
480 BOOST_CHECK_EQUAL( c.lower_bound(), 1u );
481 std::vector< boost::fibers::fiber::id > ids;
482 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&ids](){
483 ids.push_back( boost::this_fiber::get_id() );
484 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
485
486 ids.push_back( boost::this_fiber::get_id() );
487 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 2) );
488
489 ids.push_back( boost::this_fiber::get_id() );
490 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 3) );
491
492 ids.push_back( boost::this_fiber::get_id() );
493 // would be blocked because channel is full
494 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 4) );
495
496 ids.push_back( boost::this_fiber::get_id() );
497 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 5) );
498
499 ids.push_back( boost::this_fiber::get_id() );
500 });
501 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,&ids](){
502 ids.push_back( boost::this_fiber::get_id() );
503 BOOST_CHECK_EQUAL( 1, c.value_pop() );
504
505 // let other fiber run
506 boost::this_fiber::yield();
507
508 ids.push_back( boost::this_fiber::get_id() );
509 BOOST_CHECK_EQUAL( 2, c.value_pop() );
510
511 // let other fiber run
512 boost::this_fiber::yield();
513
514 ids.push_back( boost::this_fiber::get_id() );
515 BOOST_CHECK_EQUAL( 3, c.value_pop() );
516
517 ids.push_back( boost::this_fiber::get_id() );
518 BOOST_CHECK_EQUAL( 4, c.value_pop() );
519
520 ids.push_back( boost::this_fiber::get_id() );
521 BOOST_CHECK_EQUAL( 5, c.value_pop() );
522
523 ids.push_back( boost::this_fiber::get_id() );
524 });
525 boost::fibers::fiber::id id1 = f1.get_id();
526 boost::fibers::fiber::id id2 = f2.get_id();
527 f1.join();
528 f2.join();
529 BOOST_CHECK_EQUAL( 12u, ids.size() );
530 BOOST_CHECK_EQUAL( id1, ids[0]); // f1 pushes 1
531 BOOST_CHECK_EQUAL( id1, ids[1]); // f1 pushes 2
532 BOOST_CHECK_EQUAL( id1, ids[2]); // f1 pushes 3
533 BOOST_CHECK_EQUAL( id1, ids[3]); // f1 blocks in push( 4) (channel is full)
534 BOOST_CHECK_EQUAL( id2, ids[4]); // f2 resumes and pops 1, f1 gets NOT ready to push 4, f2 yields
535 BOOST_CHECK_EQUAL( id2, ids[5]); // f2 pops 2, f1 gets ready to push 4 (lwm == size == 1), f2 yields
536 BOOST_CHECK_EQUAL( id1, ids[6]); // f1 resumes and pushes 4 + 5
537 BOOST_CHECK_EQUAL( id1, ids[7]); // f1 completes
538 BOOST_CHECK_EQUAL( id2, ids[8]); // f2 resumes and pops 3
539 BOOST_CHECK_EQUAL( id2, ids[9]); // f2 pops 4
540 BOOST_CHECK_EQUAL( id2, ids[10]); // f2 pops 5
541 BOOST_CHECK_EQUAL( id2, ids[11]); // f2 completes
542}
543
544void test_wm_4() {
545 boost::fibers::bounded_channel< int > c( 3, 1);
546 std::vector< boost::fibers::fiber::id > ids;
547 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&ids](){
548 ids.push_back( boost::this_fiber::get_id() );
549 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
550
551 ids.push_back( boost::this_fiber::get_id() );
552 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 2) );
553
554 ids.push_back( boost::this_fiber::get_id() );
555 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 3) );
556
557 ids.push_back( boost::this_fiber::get_id() );
558 // would be blocked because channel is full
559 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 4) );
560
561 ids.push_back( boost::this_fiber::get_id() );
562 });
563 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,&ids](){
564 ids.push_back( boost::this_fiber::get_id() );
565 BOOST_CHECK_EQUAL( 1, c.value_pop() );
566
567 // let potential other fibers run
568 boost::this_fiber::yield();
569
570 ids.push_back( boost::this_fiber::get_id() );
571 BOOST_CHECK_EQUAL( 2, c.value_pop() );
572
573 // let potential other fibers run
574 boost::this_fiber::yield();
575
576 ids.push_back( boost::this_fiber::get_id() );
577 BOOST_CHECK_EQUAL( 3, c.value_pop() );
578
579 // let potential other fibers run
580 boost::this_fiber::yield();
581
582 ids.push_back( boost::this_fiber::get_id() );
583 // would block because channel is empty
584 BOOST_CHECK_EQUAL( 4, c.value_pop() );
585
586 ids.push_back( boost::this_fiber::get_id() );
587 });
588 boost::fibers::fiber::id id1 = f1.get_id();
589 boost::fibers::fiber::id id2 = f2.get_id();
590 f1.join();
591 f2.join();
592 BOOST_CHECK_EQUAL( 10u, ids.size() );
593 BOOST_CHECK_EQUAL( id1, ids[0]); // f1 pushes 1
594 BOOST_CHECK_EQUAL( id1, ids[1]); // f1 pushes 2
595 BOOST_CHECK_EQUAL( id1, ids[2]); // f1 pushes 3
596 BOOST_CHECK_EQUAL( id1, ids[3]); // f1 blocks in push( 4) ( channel full)
597 BOOST_CHECK_EQUAL( id2, ids[4]); // f2 resumes and pops 1, f1 gets NOT ready to push 4, f2 yields
598 BOOST_CHECK_EQUAL( id2, ids[5]); // f2 pops 2, f1 gets ready to push 4 (lwm == size == 1), f2 yields
599 BOOST_CHECK_EQUAL( id1, ids[6]); // f1 resumes and pushes 4, completes
600 BOOST_CHECK_EQUAL( id2, ids[7]); // f2 resumes and pops 3
601 BOOST_CHECK_EQUAL( id2, ids[8]); // f2 pops 4
602 BOOST_CHECK_EQUAL( id2, ids[9]); // f2 completes
603}
604
605void test_moveable() {
606 boost::fibers::bounded_channel< moveable > c( 10);
607 moveable m1( 3), m2;
608 BOOST_CHECK( m1.state);
609 BOOST_CHECK_EQUAL( 3, m1.value);
610 BOOST_CHECK( ! m2.state);
611 BOOST_CHECK_EQUAL( -1, m2.value);
612 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( std::move( m1) ) );
613 BOOST_CHECK( ! m1.state);
614 BOOST_CHECK( ! m2.state);
615 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( m2) );
616 BOOST_CHECK( ! m1.state);
617 BOOST_CHECK_EQUAL( -1, m1.value);
618 BOOST_CHECK( m2.state);
619 BOOST_CHECK_EQUAL( 3, m2.value);
620}
621
622boost::unit_test::test_suite * init_unit_test_suite( int, char* []) {
623 boost::unit_test::test_suite * test =
624 BOOST_TEST_SUITE("Boost.Fiber: bounded_channel test suite");
625
626 test->add( BOOST_TEST_CASE( & test_zero_wm_1) );
627 test->add( BOOST_TEST_CASE( & test_zero_wm_2) );
628 test->add( BOOST_TEST_CASE( & test_hwm_less_lwm) );
629 test->add( BOOST_TEST_CASE( & test_hwm_equal_lwm) );
630 test->add( BOOST_TEST_CASE( & test_push) );
631 test->add( BOOST_TEST_CASE( & test_push_closed) );
632 test->add( BOOST_TEST_CASE( & test_try_push) );
633 test->add( BOOST_TEST_CASE( & test_try_push_closed) );
634 test->add( BOOST_TEST_CASE( & test_try_push_full) );
635 test->add( BOOST_TEST_CASE( & test_push_wait_for) );
636 test->add( BOOST_TEST_CASE( & test_push_wait_for_closed) );
637 test->add( BOOST_TEST_CASE( & test_push_wait_for_timeout) );
638 test->add( BOOST_TEST_CASE( & test_push_wait_until) );
639 test->add( BOOST_TEST_CASE( & test_push_wait_until_closed) );
640 test->add( BOOST_TEST_CASE( & test_push_wait_until_timeout) );
641 test->add( BOOST_TEST_CASE( & test_pop) );
642 test->add( BOOST_TEST_CASE( & test_pop_closed) );
643 test->add( BOOST_TEST_CASE( & test_pop_success) );
644 test->add( BOOST_TEST_CASE( & test_value_pop) );
645 test->add( BOOST_TEST_CASE( & test_value_pop_closed) );
646 test->add( BOOST_TEST_CASE( & test_value_pop_success) );
647 test->add( BOOST_TEST_CASE( & test_try_pop) );
648 test->add( BOOST_TEST_CASE( & test_try_pop_closed) );
649 test->add( BOOST_TEST_CASE( & test_try_pop_success) );
650 test->add( BOOST_TEST_CASE( & test_pop_wait_for) );
651 test->add( BOOST_TEST_CASE( & test_pop_wait_for_closed) );
652 test->add( BOOST_TEST_CASE( & test_pop_wait_for_success) );
653 test->add( BOOST_TEST_CASE( & test_pop_wait_for_timeout) );
654 test->add( BOOST_TEST_CASE( & test_pop_wait_until) );
655 test->add( BOOST_TEST_CASE( & test_pop_wait_until_closed) );
656 test->add( BOOST_TEST_CASE( & test_pop_wait_until_success) );
657 test->add( BOOST_TEST_CASE( & test_pop_wait_until_timeout) );
658 test->add( BOOST_TEST_CASE( & test_wm_1) );
659 test->add( BOOST_TEST_CASE( & test_wm_2) );
660 test->add( BOOST_TEST_CASE( & test_wm_3) );
661 test->add( BOOST_TEST_CASE( & test_wm_4) );
662 test->add( BOOST_TEST_CASE( & test_moveable) );
663
664 return test;
665}