1 // (C) Copyright 2008-10 Anthony Williams
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 #define BOOST_THREAD_VERSION 2
8 #define BOOST_TEST_MODULE Boost.Threads: futures test suite
10 #include <boost/thread/thread_only.hpp>
11 #include <boost/thread/mutex.hpp>
12 #include <boost/thread/condition.hpp>
13 #include <boost/thread/future.hpp>
18 #include <boost/thread/detail/log.hpp>
20 #include <boost/test/unit_test.hpp>
23 # pragma warning(disable: 4267) // conversion from ... to ..., possible loss of data
26 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
28 typename
boost::remove_reference
<T
>::type
&& cast_to_rval(T
&& t
)
30 return static_cast<typename
boost::remove_reference
<T
>::type
&&>(t
);
33 #if defined BOOST_THREAD_USES_MOVE
35 boost::rv
<T
>& cast_to_rval(T
& t
)
37 return boost::move(t
);
41 boost::detail::thread_move_t
<T
> cast_to_rval(T
& t
)
43 return boost::move(t
);
53 BOOST_THREAD_MOVABLE_ONLY(X
)
57 X(BOOST_THREAD_RV_REF(X
) other
):
58 i(BOOST_THREAD_RV(other
).i
)
60 BOOST_THREAD_RV(other
).i
=0;
62 X
& operator=(BOOST_THREAD_RV_REF(X
) other
)
64 i
=BOOST_THREAD_RV(other
).i
;
65 BOOST_THREAD_RV(other
).i
=0;
72 BOOST_THREAD_DCL_MOVABLE(X
)
80 int throw_runtime_error()
82 throw std::runtime_error("42");
85 void set_promise_thread(boost::promise
<int>* p
)
93 void set_promise_exception_thread(boost::promise
<int>* p
)
95 p
->set_exception(boost::copy_exception(my_exception()));
99 BOOST_AUTO_TEST_CASE(test_store_value_from_thread
)
101 BOOST_DETAIL_THREAD_LOG
;
103 boost::promise
<int> pi2
;
104 BOOST_DETAIL_THREAD_LOG
;
105 boost::unique_future
<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2
.get_future()));
106 BOOST_DETAIL_THREAD_LOG
;
107 boost::thread(set_promise_thread
,&pi2
);
108 BOOST_DETAIL_THREAD_LOG
;
110 BOOST_DETAIL_THREAD_LOG
;
112 BOOST_DETAIL_THREAD_LOG
;
113 BOOST_CHECK(fi2
.is_ready());
114 BOOST_DETAIL_THREAD_LOG
;
115 BOOST_CHECK(fi2
.has_value());
116 BOOST_DETAIL_THREAD_LOG
;
117 BOOST_CHECK(!fi2
.has_exception());
118 BOOST_DETAIL_THREAD_LOG
;
119 BOOST_CHECK(fi2
.get_state()==boost::future_state::ready
);
120 BOOST_DETAIL_THREAD_LOG
;
124 BOOST_CHECK(false&&"Exception thrown");
128 BOOST_AUTO_TEST_CASE(test_store_exception
)
130 BOOST_DETAIL_THREAD_LOG
;
131 boost::promise
<int> pi3
;
132 boost::unique_future
<int> fi3(BOOST_THREAD_MAKE_RV_REF(pi3
.get_future()));
133 boost::thread(set_promise_exception_thread
,&pi3
);
144 BOOST_CHECK(fi3
.is_ready());
145 BOOST_CHECK(!fi3
.has_value());
146 BOOST_CHECK(fi3
.has_exception());
147 BOOST_CHECK(fi3
.get_state()==boost::future_state::ready
);
150 BOOST_AUTO_TEST_CASE(test_initial_state
)
152 BOOST_DETAIL_THREAD_LOG
;
153 boost::unique_future
<int> fi
;
154 BOOST_CHECK(!fi
.is_ready());
155 BOOST_CHECK(!fi
.has_value());
156 BOOST_CHECK(!fi
.has_exception());
157 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
165 catch(boost::future_uninitialized
)
171 BOOST_AUTO_TEST_CASE(test_waiting_future
)
173 BOOST_DETAIL_THREAD_LOG
;
174 boost::promise
<int> pi
;
175 boost::unique_future
<int> fi
;
176 fi
=BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
179 BOOST_CHECK(!fi
.is_ready());
180 BOOST_CHECK(!fi
.has_value());
181 BOOST_CHECK(!fi
.has_exception());
182 BOOST_CHECK(fi
.get_state()==boost::future_state::waiting
);
186 BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice
)
188 BOOST_DETAIL_THREAD_LOG
;
189 boost::promise
<int> pi
;
190 BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
197 catch(boost::future_already_retrieved
&)
203 BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state
)
205 BOOST_DETAIL_THREAD_LOG
;
206 boost::promise
<int> pi
;
207 boost::unique_future
<int> fi
;
208 fi
=BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
212 BOOST_CHECK(fi
.is_ready());
213 BOOST_CHECK(fi
.has_value());
214 BOOST_CHECK(!fi
.has_exception());
215 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
218 BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved
)
220 BOOST_DETAIL_THREAD_LOG
;
221 boost::promise
<int> pi
;
222 boost::unique_future
<int> fi
;
223 fi
=BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
228 BOOST_CHECK(i
=fi
.get());
230 BOOST_CHECK(fi
.is_ready());
231 BOOST_CHECK(fi
.has_value());
232 BOOST_CHECK(!fi
.has_exception());
233 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
236 BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved
)
238 BOOST_DETAIL_THREAD_LOG
;
239 // boost::promise<int> pi;
240 // boost::unique_future<int> fi;
241 // fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
246 // BOOST_CHECK(i=fi.get());
247 // BOOST_CHECK(i==42);
248 // BOOST_CHECK(fi.is_ready());
249 // BOOST_CHECK(fi.has_value());
250 // BOOST_CHECK(!fi.has_exception());
251 // BOOST_CHECK(fi.get_state()==boost::future_state::ready);
254 BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting
)
256 BOOST_DETAIL_THREAD_LOG
;
257 boost::packaged_task
<int> pt(make_int
);
258 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
260 BOOST_CHECK(!fi
.is_ready());
261 BOOST_CHECK(!fi
.has_value());
262 BOOST_CHECK(!fi
.has_exception());
263 BOOST_CHECK(fi
.get_state()==boost::future_state::waiting
);
267 BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future
)
269 BOOST_DETAIL_THREAD_LOG
;
270 boost::packaged_task
<int> pt(make_int
);
271 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
276 BOOST_CHECK(fi
.is_ready());
277 BOOST_CHECK(fi
.has_value());
278 BOOST_CHECK(!fi
.has_exception());
279 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
280 BOOST_CHECK(i
=fi
.get());
284 BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws
)
286 BOOST_DETAIL_THREAD_LOG
;
287 boost::packaged_task
<int> pt(make_int
);
295 catch(boost::task_already_started
)
302 BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task
)
304 BOOST_DETAIL_THREAD_LOG
;
305 boost::packaged_task
<int> pt(make_int
);
312 catch(boost::future_already_retrieved
)
318 BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws
)
320 BOOST_DETAIL_THREAD_LOG
;
321 boost::packaged_task
<int> pt(throw_runtime_error
);
322 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
326 BOOST_CHECK(fi
.is_ready());
327 BOOST_CHECK(!fi
.has_value());
328 BOOST_CHECK(fi
.has_exception());
329 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
335 catch(std::exception
&)
341 BOOST_CHECK(!"Unknown exception thrown");
346 BOOST_AUTO_TEST_CASE(test_void_promise
)
348 BOOST_DETAIL_THREAD_LOG
;
349 boost::promise
<void> p
;
350 boost::unique_future
<void> f(BOOST_THREAD_MAKE_RV_REF(p
.get_future()));
352 BOOST_CHECK(f
.is_ready());
353 BOOST_CHECK(f
.has_value());
354 BOOST_CHECK(!f
.has_exception());
355 BOOST_CHECK(f
.get_state()==boost::future_state::ready
);
359 BOOST_AUTO_TEST_CASE(test_reference_promise
)
361 BOOST_DETAIL_THREAD_LOG
;
362 boost::promise
<int&> p
;
363 boost::unique_future
<int&> f(BOOST_THREAD_MAKE_RV_REF(p
.get_future()));
366 BOOST_CHECK(f
.is_ready());
367 BOOST_CHECK(f
.has_value());
368 BOOST_CHECK(!f
.has_exception());
369 BOOST_CHECK(f
.get_state()==boost::future_state::ready
);
370 BOOST_CHECK(&f
.get()==&i
);
376 BOOST_AUTO_TEST_CASE(test_task_returning_void
)
378 BOOST_DETAIL_THREAD_LOG
;
379 boost::packaged_task
<void> pt(do_nothing
);
380 boost::unique_future
<void> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
384 BOOST_CHECK(fi
.is_ready());
385 BOOST_CHECK(fi
.has_value());
386 BOOST_CHECK(!fi
.has_exception());
387 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
390 int global_ref_target
=0;
394 return global_ref_target
;
397 BOOST_AUTO_TEST_CASE(test_task_returning_reference
)
399 BOOST_DETAIL_THREAD_LOG
;
400 boost::packaged_task
<int&> pt(return_ref
);
401 boost::unique_future
<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
405 BOOST_CHECK(fi
.is_ready());
406 BOOST_CHECK(fi
.has_value());
407 BOOST_CHECK(!fi
.has_exception());
408 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
410 BOOST_CHECK(&i
==&global_ref_target
);
413 BOOST_AUTO_TEST_CASE(test_shared_future
)
415 BOOST_DETAIL_THREAD_LOG
;
416 boost::packaged_task
<int> pt(make_int
);
417 boost::unique_future
<int> fi
=pt
.get_future();
419 boost::shared_future
<int> sf(::cast_to_rval(fi
));
420 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
425 BOOST_CHECK(sf
.is_ready());
426 BOOST_CHECK(sf
.has_value());
427 BOOST_CHECK(!sf
.has_exception());
428 BOOST_CHECK(sf
.get_state()==boost::future_state::ready
);
429 BOOST_CHECK(i
=sf
.get());
433 BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together
)
435 BOOST_DETAIL_THREAD_LOG
;
436 boost::packaged_task
<int> pt(make_int
);
437 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
439 boost::shared_future
<int> sf(::cast_to_rval(fi
));
440 boost::shared_future
<int> sf2(sf
);
441 boost::shared_future
<int> sf3
;
443 BOOST_CHECK(sf
.get_state()==boost::future_state::waiting
);
444 BOOST_CHECK(sf2
.get_state()==boost::future_state::waiting
);
445 BOOST_CHECK(sf3
.get_state()==boost::future_state::waiting
);
450 BOOST_CHECK(sf
.is_ready());
451 BOOST_CHECK(sf
.has_value());
452 BOOST_CHECK(!sf
.has_exception());
453 BOOST_CHECK(sf
.get_state()==boost::future_state::ready
);
454 BOOST_CHECK(i
=sf
.get());
457 BOOST_CHECK(sf2
.is_ready());
458 BOOST_CHECK(sf2
.has_value());
459 BOOST_CHECK(!sf2
.has_exception());
460 BOOST_CHECK(sf2
.get_state()==boost::future_state::ready
);
461 BOOST_CHECK(i
=sf2
.get());
464 BOOST_CHECK(sf3
.is_ready());
465 BOOST_CHECK(sf3
.has_value());
466 BOOST_CHECK(!sf3
.has_exception());
467 BOOST_CHECK(sf3
.get_state()==boost::future_state::ready
);
468 BOOST_CHECK(i
=sf3
.get());
472 BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future
)
474 BOOST_DETAIL_THREAD_LOG
;
475 boost::packaged_task
<int> pt(make_int
);
476 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
478 boost::shared_future
<int> sf
;
479 sf
=::cast_to_rval(fi
);
480 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
482 BOOST_CHECK(!sf
.is_ready());
483 BOOST_CHECK(!sf
.has_value());
484 BOOST_CHECK(!sf
.has_exception());
485 BOOST_CHECK(sf
.get_state()==boost::future_state::waiting
);
488 BOOST_AUTO_TEST_CASE(test_shared_future_void
)
490 BOOST_DETAIL_THREAD_LOG
;
491 boost::packaged_task
<void> pt(do_nothing
);
492 boost::unique_future
<void> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
494 boost::shared_future
<void> sf(::cast_to_rval(fi
));
495 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
499 BOOST_CHECK(sf
.is_ready());
500 BOOST_CHECK(sf
.has_value());
501 BOOST_CHECK(!sf
.has_exception());
502 BOOST_CHECK(sf
.get_state()==boost::future_state::ready
);
506 BOOST_AUTO_TEST_CASE(test_shared_future_ref
)
508 BOOST_DETAIL_THREAD_LOG
;
509 boost::promise
<int&> p
;
510 boost::shared_future
<int&> f(BOOST_THREAD_MAKE_RV_REF(p
.get_future()));
513 BOOST_CHECK(f
.is_ready());
514 BOOST_CHECK(f
.has_value());
515 BOOST_CHECK(!f
.has_exception());
516 BOOST_CHECK(f
.get_state()==boost::future_state::ready
);
517 BOOST_CHECK(&f
.get()==&i
);
520 BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise
)
522 BOOST_DETAIL_THREAD_LOG
;
523 boost::promise
<int> pi
;
524 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
526 boost::promise
<int> pi2(::cast_to_rval(pi
));
527 boost::unique_future
<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
530 BOOST_CHECK(fi
.is_ready());
531 BOOST_CHECK(!fi2
.is_ready());
532 BOOST_CHECK(fi
.get()==3);
534 BOOST_CHECK(fi2
.is_ready());
535 BOOST_CHECK(fi2
.get()==42);
538 BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise
)
540 BOOST_DETAIL_THREAD_LOG
;
541 boost::promise
<void> pi
;
542 boost::unique_future
<void> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
544 boost::promise
<void> pi2(::cast_to_rval(pi
));
545 boost::unique_future
<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
548 BOOST_CHECK(fi
.is_ready());
549 BOOST_CHECK(!fi2
.is_ready());
551 BOOST_CHECK(fi2
.is_ready());
554 BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt
)
556 BOOST_DETAIL_THREAD_LOG
;
557 boost::promise
<X
> pt
;
558 boost::unique_future
<X
> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
562 BOOST_CHECK(res
.i
==42);
565 BOOST_AUTO_TEST_CASE(test_unique_future_for_string
)
567 BOOST_DETAIL_THREAD_LOG
;
568 boost::promise
<std::string
> pt
;
569 boost::unique_future
<std::string
> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
571 pt
.set_value(std::string("hello"));
572 std::string
res(fi
.get());
573 BOOST_CHECK(res
=="hello");
575 boost::promise
<std::string
> pt2
;
576 fi
=BOOST_THREAD_MAKE_RV_REF(pt2
.get_future());
578 std::string
const s
="goodbye";
582 BOOST_CHECK(res
=="goodbye");
584 boost::promise
<std::string
> pt3
;
585 fi
=BOOST_THREAD_MAKE_RV_REF(pt3
.get_future());
587 std::string s2
="foo";
591 BOOST_CHECK(res
=="foo");
594 boost::mutex callback_mutex
;
595 unsigned callback_called
=0;
597 void wait_callback(boost::promise
<int>& pi
)
599 boost::lock_guard
<boost::mutex
> lk(callback_mutex
);
610 void do_nothing_callback(boost::promise
<int>& /*pi*/)
612 boost::lock_guard
<boost::mutex
> lk(callback_mutex
);
616 BOOST_AUTO_TEST_CASE(test_wait_callback
)
618 BOOST_DETAIL_THREAD_LOG
;
620 boost::promise
<int> pi
;
621 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
622 pi
.set_wait_callback(wait_callback
);
624 BOOST_CHECK(callback_called
);
625 BOOST_CHECK(fi
.get()==42);
628 BOOST_CHECK(callback_called
==1);
631 BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait
)
633 BOOST_DETAIL_THREAD_LOG
;
635 boost::promise
<int> pi
;
636 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
637 pi
.set_wait_callback(do_nothing_callback
);
638 bool success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
639 BOOST_CHECK(callback_called
);
640 BOOST_CHECK(!success
);
641 success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
642 BOOST_CHECK(!success
);
643 success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
644 BOOST_CHECK(!success
);
645 BOOST_CHECK(callback_called
==3);
647 success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
648 BOOST_CHECK(success
);
649 BOOST_CHECK(callback_called
==3);
650 BOOST_CHECK(fi
.get()==42);
651 BOOST_CHECK(callback_called
==3);
655 void wait_callback_for_task(boost::packaged_task
<int>& pt
)
657 BOOST_DETAIL_THREAD_LOG
;
658 boost::lock_guard
<boost::mutex
> lk(callback_mutex
);
670 BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task
)
672 BOOST_DETAIL_THREAD_LOG
;
674 boost::packaged_task
<int> pt(make_int
);
675 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
676 pt
.set_wait_callback(wait_callback_for_task
);
678 BOOST_CHECK(callback_called
);
679 BOOST_CHECK(fi
.get()==42);
682 BOOST_CHECK(callback_called
==1);
685 BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved
)
687 BOOST_DETAIL_THREAD_LOG
;
688 boost::packaged_task
<int> pt(make_int
);
690 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
692 BOOST_CHECK(!fi
.is_ready());
694 boost::packaged_task
<int> pt2(::cast_to_rval(pt
));
696 BOOST_CHECK(!fi
.is_ready());
700 BOOST_CHECK(!"Can invoke moved task!");
702 catch(boost::task_moved
&)
706 BOOST_CHECK(!fi
.is_ready());
710 BOOST_CHECK(fi
.is_ready());
713 BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise
)
715 BOOST_DETAIL_THREAD_LOG
;
716 boost::unique_future
<int> f
;
719 boost::promise
<int> p
;
720 f
=BOOST_THREAD_MAKE_RV_REF(p
.get_future());
722 BOOST_CHECK(f
.is_ready());
723 BOOST_CHECK(f
.has_exception());
728 catch(boost::broken_promise
&)
733 BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise
)
735 BOOST_DETAIL_THREAD_LOG
;
736 boost::unique_future
<int> f
;
739 boost::packaged_task
<int> p(make_int
);
740 f
=BOOST_THREAD_MAKE_RV_REF(p
.get_future());
742 BOOST_CHECK(f
.is_ready());
743 BOOST_CHECK(f
.has_exception());
748 catch(boost::broken_promise
&)
753 int make_int_slowly()
755 boost::this_thread::sleep(boost::posix_time::seconds(1));
759 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1
)
761 BOOST_DETAIL_THREAD_LOG
;
762 boost::packaged_task
<int> pt(make_int_slowly
);
763 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
764 boost::packaged_task
<int> pt2(make_int_slowly
);
765 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
767 boost::thread(::cast_to_rval(pt
));
769 unsigned const future
=boost::wait_for_any(f1
,f2
);
771 BOOST_CHECK(future
==0);
772 BOOST_CHECK(f1
.is_ready());
773 BOOST_CHECK(!f2
.is_ready());
774 BOOST_CHECK(f1
.get()==42);
777 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2
)
779 BOOST_DETAIL_THREAD_LOG
;
780 boost::packaged_task
<int> pt(make_int_slowly
);
781 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
782 boost::packaged_task
<int> pt2(make_int_slowly
);
783 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
785 boost::thread(::cast_to_rval(pt2
));
787 unsigned const future
=boost::wait_for_any(f1
,f2
);
789 BOOST_CHECK(future
==1);
790 BOOST_CHECK(!f1
.is_ready());
791 BOOST_CHECK(f2
.is_ready());
792 BOOST_CHECK(f2
.get()==42);
795 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1
)
797 BOOST_DETAIL_THREAD_LOG
;
798 boost::packaged_task
<int> pt(make_int_slowly
);
799 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
800 boost::packaged_task
<int> pt2(make_int_slowly
);
801 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
802 boost::packaged_task
<int> pt3(make_int_slowly
);
803 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
805 boost::thread(::cast_to_rval(pt
));
807 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
);
809 BOOST_CHECK(future
==0);
810 BOOST_CHECK(f1
.is_ready());
811 BOOST_CHECK(!f2
.is_ready());
812 BOOST_CHECK(!f3
.is_ready());
813 BOOST_CHECK(f1
.get()==42);
816 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2
)
818 BOOST_DETAIL_THREAD_LOG
;
819 boost::packaged_task
<int> pt(make_int_slowly
);
820 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
821 boost::packaged_task
<int> pt2(make_int_slowly
);
822 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
823 boost::packaged_task
<int> pt3(make_int_slowly
);
824 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
826 boost::thread(::cast_to_rval(pt2
));
828 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
);
830 BOOST_CHECK(future
==1);
831 BOOST_CHECK(!f1
.is_ready());
832 BOOST_CHECK(f2
.is_ready());
833 BOOST_CHECK(!f3
.is_ready());
834 BOOST_CHECK(f2
.get()==42);
837 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3
)
839 BOOST_DETAIL_THREAD_LOG
;
840 boost::packaged_task
<int> pt(make_int_slowly
);
841 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
842 boost::packaged_task
<int> pt2(make_int_slowly
);
843 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
844 boost::packaged_task
<int> pt3(make_int_slowly
);
845 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
847 boost::thread(::cast_to_rval(pt3
));
849 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
);
851 BOOST_CHECK(future
==2);
852 BOOST_CHECK(!f1
.is_ready());
853 BOOST_CHECK(!f2
.is_ready());
854 BOOST_CHECK(f3
.is_ready());
855 BOOST_CHECK(f3
.get()==42);
858 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1
)
860 BOOST_DETAIL_THREAD_LOG
;
861 boost::packaged_task
<int> pt(make_int_slowly
);
862 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
863 boost::packaged_task
<int> pt2(make_int_slowly
);
864 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
865 boost::packaged_task
<int> pt3(make_int_slowly
);
866 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
867 boost::packaged_task
<int> pt4(make_int_slowly
);
868 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
870 boost::thread(::cast_to_rval(pt
));
872 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
874 BOOST_CHECK(future
==0);
875 BOOST_CHECK(f1
.is_ready());
876 BOOST_CHECK(!f2
.is_ready());
877 BOOST_CHECK(!f3
.is_ready());
878 BOOST_CHECK(!f4
.is_ready());
879 BOOST_CHECK(f1
.get()==42);
882 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2
)
884 BOOST_DETAIL_THREAD_LOG
;
885 boost::packaged_task
<int> pt(make_int_slowly
);
886 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
887 boost::packaged_task
<int> pt2(make_int_slowly
);
888 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
889 boost::packaged_task
<int> pt3(make_int_slowly
);
890 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
891 boost::packaged_task
<int> pt4(make_int_slowly
);
892 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
894 boost::thread(::cast_to_rval(pt2
));
896 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
898 BOOST_CHECK(future
==1);
899 BOOST_CHECK(!f1
.is_ready());
900 BOOST_CHECK(f2
.is_ready());
901 BOOST_CHECK(!f3
.is_ready());
902 BOOST_CHECK(!f4
.is_ready());
903 BOOST_CHECK(f2
.get()==42);
906 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3
)
908 BOOST_DETAIL_THREAD_LOG
;
909 boost::packaged_task
<int> pt(make_int_slowly
);
910 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
911 boost::packaged_task
<int> pt2(make_int_slowly
);
912 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
913 boost::packaged_task
<int> pt3(make_int_slowly
);
914 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
915 boost::packaged_task
<int> pt4(make_int_slowly
);
916 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
918 boost::thread(::cast_to_rval(pt3
));
920 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
922 BOOST_CHECK(future
==2);
923 BOOST_CHECK(!f1
.is_ready());
924 BOOST_CHECK(!f2
.is_ready());
925 BOOST_CHECK(f3
.is_ready());
926 BOOST_CHECK(!f4
.is_ready());
927 BOOST_CHECK(f3
.get()==42);
930 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4
)
932 BOOST_DETAIL_THREAD_LOG
;
933 boost::packaged_task
<int> pt(make_int_slowly
);
934 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
935 boost::packaged_task
<int> pt2(make_int_slowly
);
936 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
937 boost::packaged_task
<int> pt3(make_int_slowly
);
938 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
939 boost::packaged_task
<int> pt4(make_int_slowly
);
940 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
942 boost::thread(::cast_to_rval(pt4
));
944 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
946 BOOST_CHECK(future
==3);
947 BOOST_CHECK(!f1
.is_ready());
948 BOOST_CHECK(!f2
.is_ready());
949 BOOST_CHECK(!f3
.is_ready());
950 BOOST_CHECK(f4
.is_ready());
951 BOOST_CHECK(f4
.get()==42);
954 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1
)
956 BOOST_DETAIL_THREAD_LOG
;
957 boost::packaged_task
<int> pt(make_int_slowly
);
958 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
959 boost::packaged_task
<int> pt2(make_int_slowly
);
960 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
961 boost::packaged_task
<int> pt3(make_int_slowly
);
962 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
963 boost::packaged_task
<int> pt4(make_int_slowly
);
964 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
965 boost::packaged_task
<int> pt5(make_int_slowly
);
966 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
968 boost::thread(::cast_to_rval(pt
));
970 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
972 BOOST_CHECK(future
==0);
973 BOOST_CHECK(f1
.is_ready());
974 BOOST_CHECK(!f2
.is_ready());
975 BOOST_CHECK(!f3
.is_ready());
976 BOOST_CHECK(!f4
.is_ready());
977 BOOST_CHECK(!f5
.is_ready());
978 BOOST_CHECK(f1
.get()==42);
981 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2
)
983 BOOST_DETAIL_THREAD_LOG
;
984 boost::packaged_task
<int> pt(make_int_slowly
);
985 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
986 boost::packaged_task
<int> pt2(make_int_slowly
);
987 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
988 boost::packaged_task
<int> pt3(make_int_slowly
);
989 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
990 boost::packaged_task
<int> pt4(make_int_slowly
);
991 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
992 boost::packaged_task
<int> pt5(make_int_slowly
);
993 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
995 boost::thread(::cast_to_rval(pt2
));
997 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
999 BOOST_CHECK(future
==1);
1000 BOOST_CHECK(!f1
.is_ready());
1001 BOOST_CHECK(f2
.is_ready());
1002 BOOST_CHECK(!f3
.is_ready());
1003 BOOST_CHECK(!f4
.is_ready());
1004 BOOST_CHECK(!f5
.is_ready());
1005 BOOST_CHECK(f2
.get()==42);
1007 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3
)
1009 BOOST_DETAIL_THREAD_LOG
;
1010 boost::packaged_task
<int> pt(make_int_slowly
);
1011 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1012 boost::packaged_task
<int> pt2(make_int_slowly
);
1013 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1014 boost::packaged_task
<int> pt3(make_int_slowly
);
1015 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
1016 boost::packaged_task
<int> pt4(make_int_slowly
);
1017 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
1018 boost::packaged_task
<int> pt5(make_int_slowly
);
1019 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
1021 boost::thread(::cast_to_rval(pt3
));
1023 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
1025 BOOST_CHECK(future
==2);
1026 BOOST_CHECK(!f1
.is_ready());
1027 BOOST_CHECK(!f2
.is_ready());
1028 BOOST_CHECK(f3
.is_ready());
1029 BOOST_CHECK(!f4
.is_ready());
1030 BOOST_CHECK(!f5
.is_ready());
1031 BOOST_CHECK(f3
.get()==42);
1033 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4
)
1035 BOOST_DETAIL_THREAD_LOG
;
1036 boost::packaged_task
<int> pt(make_int_slowly
);
1037 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1038 boost::packaged_task
<int> pt2(make_int_slowly
);
1039 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1040 boost::packaged_task
<int> pt3(make_int_slowly
);
1041 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
1042 boost::packaged_task
<int> pt4(make_int_slowly
);
1043 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
1044 boost::packaged_task
<int> pt5(make_int_slowly
);
1045 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
1047 boost::thread(::cast_to_rval(pt4
));
1049 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
1051 BOOST_CHECK(future
==3);
1052 BOOST_CHECK(!f1
.is_ready());
1053 BOOST_CHECK(!f2
.is_ready());
1054 BOOST_CHECK(!f3
.is_ready());
1055 BOOST_CHECK(f4
.is_ready());
1056 BOOST_CHECK(!f5
.is_ready());
1057 BOOST_CHECK(f4
.get()==42);
1059 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5
)
1061 BOOST_DETAIL_THREAD_LOG
;
1062 boost::packaged_task
<int> pt(make_int_slowly
);
1063 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1064 boost::packaged_task
<int> pt2(make_int_slowly
);
1065 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1066 boost::packaged_task
<int> pt3(make_int_slowly
);
1067 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
1068 boost::packaged_task
<int> pt4(make_int_slowly
);
1069 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
1070 boost::packaged_task
<int> pt5(make_int_slowly
);
1071 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
1073 boost::thread(::cast_to_rval(pt5
));
1075 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
1077 BOOST_CHECK(future
==4);
1078 BOOST_CHECK(!f1
.is_ready());
1079 BOOST_CHECK(!f2
.is_ready());
1080 BOOST_CHECK(!f3
.is_ready());
1081 BOOST_CHECK(!f4
.is_ready());
1082 BOOST_CHECK(f5
.is_ready());
1083 BOOST_CHECK(f5
.get()==42);
1086 BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks
)
1088 BOOST_DETAIL_THREAD_LOG
;
1090 boost::packaged_task
<int> pt(make_int_slowly
);
1091 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1092 boost::packaged_task
<int> pt2(make_int_slowly
);
1093 boost::unique_future
<int> fi2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1094 pt
.set_wait_callback(wait_callback_for_task
);
1096 boost::thread(::cast_to_rval(pt
));
1098 boost::wait_for_any(fi
,fi2
);
1099 BOOST_CHECK(callback_called
==1);
1100 BOOST_CHECK(fi
.get()==42);
1103 BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range
)
1105 BOOST_DETAIL_THREAD_LOG
;
1106 unsigned const count
=10;
1107 for(unsigned i
=0;i
<count
;++i
)
1109 boost::packaged_task
<int> tasks
[count
];
1110 boost::unique_future
<int> futures
[count
];
1111 for(unsigned j
=0;j
<count
;++j
)
1113 tasks
[j
]=boost::packaged_task
<int>(make_int_slowly
);
1114 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(tasks
[j
].get_future());
1116 boost::thread(::cast_to_rval(tasks
[i
]));
1118 BOOST_CHECK(boost::wait_for_any(futures
,futures
)==futures
);
1120 boost::unique_future
<int>* const future
=boost::wait_for_any(futures
,futures
+count
);
1122 BOOST_CHECK(future
==(futures
+i
));
1123 for(unsigned j
=0;j
<count
;++j
)
1127 BOOST_CHECK(!futures
[j
].is_ready());
1131 BOOST_CHECK(futures
[j
].is_ready());
1134 BOOST_CHECK(futures
[i
].get()==42);
1138 BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range
)
1140 BOOST_DETAIL_THREAD_LOG
;
1141 unsigned const count
=10;
1142 boost::unique_future
<int> futures
[count
];
1143 for(unsigned j
=0;j
<count
;++j
)
1145 boost::packaged_task
<int> task(make_int_slowly
);
1146 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1147 boost::thread(::cast_to_rval(task
));
1150 boost::wait_for_all(futures
,futures
+count
);
1152 for(unsigned j
=0;j
<count
;++j
)
1154 BOOST_CHECK(futures
[j
].is_ready());
1158 BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures
)
1160 BOOST_DETAIL_THREAD_LOG
;
1161 unsigned const count
=2;
1162 boost::unique_future
<int> futures
[count
];
1163 for(unsigned j
=0;j
<count
;++j
)
1165 boost::packaged_task
<int> task(make_int_slowly
);
1166 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1167 boost::thread(::cast_to_rval(task
));
1170 boost::wait_for_all(futures
[0],futures
[1]);
1172 for(unsigned j
=0;j
<count
;++j
)
1174 BOOST_CHECK(futures
[j
].is_ready());
1178 BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures
)
1180 BOOST_DETAIL_THREAD_LOG
;
1181 unsigned const count
=3;
1182 boost::unique_future
<int> futures
[count
];
1183 for(unsigned j
=0;j
<count
;++j
)
1185 boost::packaged_task
<int> task(make_int_slowly
);
1186 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1187 boost::thread(::cast_to_rval(task
));
1190 boost::wait_for_all(futures
[0],futures
[1],futures
[2]);
1192 for(unsigned j
=0;j
<count
;++j
)
1194 BOOST_CHECK(futures
[j
].is_ready());
1198 BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures
)
1200 BOOST_DETAIL_THREAD_LOG
;
1201 unsigned const count
=4;
1202 boost::unique_future
<int> futures
[count
];
1203 for(unsigned j
=0;j
<count
;++j
)
1205 boost::packaged_task
<int> task(make_int_slowly
);
1206 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1207 boost::thread(::cast_to_rval(task
));
1210 boost::wait_for_all(futures
[0],futures
[1],futures
[2],futures
[3]);
1212 for(unsigned j
=0;j
<count
;++j
)
1214 BOOST_CHECK(futures
[j
].is_ready());
1218 BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures
)
1220 BOOST_DETAIL_THREAD_LOG
;
1221 unsigned const count
=5;
1222 boost::unique_future
<int> futures
[count
];
1223 for(unsigned j
=0;j
<count
;++j
)
1225 boost::packaged_task
<int> task(make_int_slowly
);
1226 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1227 boost::thread(::cast_to_rval(task
));
1230 boost::wait_for_all(futures
[0],futures
[1],futures
[2],futures
[3],futures
[4]);
1232 for(unsigned j
=0;j
<count
;++j
)
1234 BOOST_CHECK(futures
[j
].is_ready());