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)
12 #include <boost/assert.hpp>
13 #include <boost/test/unit_test.hpp>
15 #include <boost/fiber/all.hpp>
31 moveable( moveable
&& other
) :
38 moveable
& operator=( moveable
&& other
) {
39 if ( this == & other
) return * this;
48 void test_zero_wm_1() {
51 boost::fibers::bounded_channel
< int > c( 0);
52 } catch ( boost::fibers::fiber_error
const&) {
58 void test_zero_wm_2() {
61 boost::fibers::bounded_channel
< int > c( 0, 0);
62 } catch ( boost::fibers::fiber_error
const&) {
68 void test_hwm_less_lwm() {
71 boost::fibers::bounded_channel
< int > c( 2, 3);
72 } catch ( boost::fibers::fiber_error
const&) {
78 void test_hwm_equal_lwm() {
81 boost::fibers::bounded_channel
< int > c( 3, 3);
82 } catch ( boost::fibers::fiber_error
const&) {
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) );
95 void test_push_closed() {
96 boost::fibers::bounded_channel
< int > c( 10);
98 BOOST_CHECK( boost::fibers::channel_op_status::closed
== c
.push( 1) );
101 void test_try_push() {
102 boost::fibers::bounded_channel
< int > c( 1);
103 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 1) );
106 void 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) );
110 BOOST_CHECK( boost::fibers::channel_op_status::closed
== c
.try_push( 2) );
113 void 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) );
120 void 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) ) );
125 void test_push_wait_for_closed() {
126 boost::fibers::bounded_channel
< int > c( 1);
128 BOOST_CHECK( boost::fibers::channel_op_status::closed
== c
.push_wait_for( 1, std::chrono::seconds( 1) ) );
131 void 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) ) );
137 void 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) ) );
143 void test_push_wait_until_closed() {
144 boost::fibers::bounded_channel
< int > c( 1);
146 BOOST_CHECK( boost::fibers::channel_op_status::closed
== c
.push_wait_until( 1,
147 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
150 void 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) ) );
159 boost::fibers::bounded_channel
< int > c( 10);
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
);
166 void test_pop_closed() {
167 boost::fibers::bounded_channel
< int > c( 10);
169 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
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
) );
176 void test_pop_success() {
177 boost::fibers::bounded_channel
< int > c( 10);
179 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&c
,&v2
](){
180 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.pop( v2
) );
182 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,v1
](){
183 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
187 BOOST_CHECK_EQUAL( v1
, v2
);
190 void test_value_pop() {
191 boost::fibers::bounded_channel
< int > c( 10);
193 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
195 BOOST_CHECK_EQUAL( v1
, v2
);
198 void test_value_pop_closed() {
199 boost::fibers::bounded_channel
< int > c( 10);
201 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
204 BOOST_CHECK_EQUAL( v1
, v2
);
208 } catch ( boost::fibers::fiber_error
const&) {
211 BOOST_CHECK( thrown
);
214 void test_value_pop_success() {
215 boost::fibers::bounded_channel
< int > c( 10);
217 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&c
,&v2
](){
220 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,v1
](){
221 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
225 BOOST_CHECK_EQUAL( v1
, v2
);
228 void test_try_pop() {
229 boost::fibers::bounded_channel
< int > c( 10);
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
);
236 void test_try_pop_closed() {
237 boost::fibers::bounded_channel
< int > c( 10);
239 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
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
) );
246 void test_try_pop_success() {
247 boost::fibers::bounded_channel
< int > c( 10);
249 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&c
,&v2
](){
250 while ( boost::fibers::channel_op_status::success
!= c
.try_pop( v2
) );
252 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,v1
](){
253 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
257 BOOST_CHECK_EQUAL( v1
, v2
);
260 void test_pop_wait_for() {
261 boost::fibers::bounded_channel
< int > c( 10);
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
);
268 void test_pop_wait_for_closed() {
269 boost::fibers::bounded_channel
< int > c( 10);
271 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
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) ) );
278 void test_pop_wait_for_success() {
279 boost::fibers::bounded_channel
< int > c( 10);
281 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&c
,&v2
](){
282 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.pop_wait_for( v2
, std::chrono::seconds( 1) ) );
284 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,v1
](){
285 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
289 BOOST_CHECK_EQUAL( v1
, v2
);
292 void test_pop_wait_for_timeout() {
293 boost::fibers::bounded_channel
< int > c( 10);
295 boost::fibers::fiber
f( boost::fibers::launch::dispatch
, [&c
,&v
](){
296 BOOST_CHECK( boost::fibers::channel_op_status::timeout
== c
.pop_wait_for( v
, std::chrono::seconds( 1) ) );
301 void test_pop_wait_until() {
302 boost::fibers::bounded_channel
< int > c( 10);
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
);
310 void test_pop_wait_until_closed() {
311 boost::fibers::bounded_channel
< int > c( 10);
313 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
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) ) );
322 void test_pop_wait_until_success() {
323 boost::fibers::bounded_channel
< int > c( 10);
325 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&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) ) );
329 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,v1
](){
330 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( v1
) );
334 BOOST_CHECK_EQUAL( v1
, v2
);
337 void test_pop_wait_until_timeout() {
338 boost::fibers::bounded_channel
< int > c( 10);
340 boost::fibers::fiber
f( boost::fibers::launch::dispatch
, [&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) ) );
348 boost::fibers::bounded_channel
< int > c( 3);
349 std::vector
< boost::fibers::fiber::id
> ids
;
350 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&c
,&ids
](){
351 ids
.push_back( boost::this_fiber::get_id() );
352 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 1) );
354 ids
.push_back( boost::this_fiber::get_id() );
355 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 2) );
357 ids
.push_back( boost::this_fiber::get_id() );
358 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 3) );
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) );
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) );
368 ids
.push_back( boost::this_fiber::get_id() );
370 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,&ids
](){
371 ids
.push_back( boost::this_fiber::get_id() );
372 BOOST_CHECK_EQUAL( 1, c
.value_pop() );
374 // let other fiber run
375 boost::this_fiber::yield();
377 ids
.push_back( boost::this_fiber::get_id() );
378 BOOST_CHECK_EQUAL( 2, c
.value_pop() );
380 ids
.push_back( boost::this_fiber::get_id() );
381 BOOST_CHECK_EQUAL( 3, c
.value_pop() );
383 ids
.push_back( boost::this_fiber::get_id() );
384 BOOST_CHECK_EQUAL( 4, c
.value_pop() );
386 ids
.push_back( boost::this_fiber::get_id() );
387 // would block because channel is empty
388 BOOST_CHECK_EQUAL( 5, c
.value_pop() );
390 ids
.push_back( boost::this_fiber::get_id() );
392 boost::fibers::fiber::id id1
= f1
.get_id();
393 boost::fibers::fiber::id id2
= f2
.get_id();
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
412 boost::fibers::bounded_channel
< int > c( 3);
413 std::vector
< boost::fibers::fiber::id
> ids
;
414 boost::fibers::fiber
f1( boost::fibers::launch::dispatch
, [&c
,&ids
](){
415 ids
.push_back( boost::this_fiber::get_id() );
416 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 1) );
418 ids
.push_back( boost::this_fiber::get_id() );
419 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 2) );
421 ids
.push_back( boost::this_fiber::get_id() );
422 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 3) );
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) );
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) );
432 ids
.push_back( boost::this_fiber::get_id() );
434 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,&ids
](){
435 ids
.push_back( boost::this_fiber::get_id() );
436 BOOST_CHECK_EQUAL( 1, c
.value_pop() );
438 // let other fiber run
439 boost::this_fiber::yield();
441 ids
.push_back( boost::this_fiber::get_id() );
442 BOOST_CHECK_EQUAL( 2, c
.value_pop() );
444 // let other fiber run
445 boost::this_fiber::yield();
447 ids
.push_back( boost::this_fiber::get_id() );
448 BOOST_CHECK_EQUAL( 3, c
.value_pop() );
450 ids
.push_back( boost::this_fiber::get_id() );
451 BOOST_CHECK_EQUAL( 4, c
.value_pop() );
453 ids
.push_back( boost::this_fiber::get_id() );
454 BOOST_CHECK_EQUAL( 5, c
.value_pop() );
456 ids
.push_back( boost::this_fiber::get_id() );
458 boost::fibers::fiber::id id1
= f1
.get_id();
459 boost::fibers::fiber::id id2
= f2
.get_id();
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
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::dispatch
, [&c
,&ids
](){
483 ids
.push_back( boost::this_fiber::get_id() );
484 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 1) );
486 ids
.push_back( boost::this_fiber::get_id() );
487 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 2) );
489 ids
.push_back( boost::this_fiber::get_id() );
490 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 3) );
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) );
496 ids
.push_back( boost::this_fiber::get_id() );
497 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 5) );
499 ids
.push_back( boost::this_fiber::get_id() );
501 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,&ids
](){
502 ids
.push_back( boost::this_fiber::get_id() );
503 BOOST_CHECK_EQUAL( 1, c
.value_pop() );
505 // let other fiber run
506 boost::this_fiber::yield();
508 ids
.push_back( boost::this_fiber::get_id() );
509 BOOST_CHECK_EQUAL( 2, c
.value_pop() );
511 // let other fiber run
512 boost::this_fiber::yield();
514 ids
.push_back( boost::this_fiber::get_id() );
515 BOOST_CHECK_EQUAL( 3, c
.value_pop() );
517 ids
.push_back( boost::this_fiber::get_id() );
518 BOOST_CHECK_EQUAL( 4, c
.value_pop() );
520 ids
.push_back( boost::this_fiber::get_id() );
521 BOOST_CHECK_EQUAL( 5, c
.value_pop() );
523 ids
.push_back( boost::this_fiber::get_id() );
525 boost::fibers::fiber::id id1
= f1
.get_id();
526 boost::fibers::fiber::id id2
= f2
.get_id();
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
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::dispatch
, [&c
,&ids
](){
548 ids
.push_back( boost::this_fiber::get_id() );
549 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 1) );
551 ids
.push_back( boost::this_fiber::get_id() );
552 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 2) );
554 ids
.push_back( boost::this_fiber::get_id() );
555 BOOST_CHECK( boost::fibers::channel_op_status::success
== c
.push( 3) );
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) );
561 ids
.push_back( boost::this_fiber::get_id() );
563 boost::fibers::fiber
f2( boost::fibers::launch::dispatch
, [&c
,&ids
](){
564 ids
.push_back( boost::this_fiber::get_id() );
565 BOOST_CHECK_EQUAL( 1, c
.value_pop() );
567 // let potential other fibers run
568 boost::this_fiber::yield();
570 ids
.push_back( boost::this_fiber::get_id() );
571 BOOST_CHECK_EQUAL( 2, c
.value_pop() );
573 // let potential other fibers run
574 boost::this_fiber::yield();
576 ids
.push_back( boost::this_fiber::get_id() );
577 BOOST_CHECK_EQUAL( 3, c
.value_pop() );
579 // let potential other fibers run
580 boost::this_fiber::yield();
582 ids
.push_back( boost::this_fiber::get_id() );
583 // would block because channel is empty
584 BOOST_CHECK_EQUAL( 4, c
.value_pop() );
586 ids
.push_back( boost::this_fiber::get_id() );
588 boost::fibers::fiber::id id1
= f1
.get_id();
589 boost::fibers::fiber::id id2
= f2
.get_id();
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
605 void test_moveable() {
606 boost::fibers::bounded_channel
< moveable
> c( 10);
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
);
622 boost::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");
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
) );