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>
19 #include <boost/test/unit_test.hpp>
22 if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
24 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
26 typename
boost::remove_reference
<T
>::type
&& cast_to_rval(T
&& t
)
28 return static_cast<typename
boost::remove_reference
<T
>::type
&&>(t
);
31 #if defined BOOST_THREAD_USES_MOVE
33 boost::rv
<T
>& cast_to_rval(T
& t
)
35 return boost::move(t
);
39 boost::detail::thread_move_t
<T
> cast_to_rval(T
& t
)
41 return boost::move(t
);
51 BOOST_THREAD_MOVABLE_ONLY(X
)
55 X(BOOST_THREAD_RV_REF(X
) other
):
56 i(BOOST_THREAD_RV(other
).i
)
58 BOOST_THREAD_RV(other
).i
=0;
60 X
& operator=(BOOST_THREAD_RV_REF(X
) other
)
62 i
=BOOST_THREAD_RV(other
).i
;
63 BOOST_THREAD_RV(other
).i
=0;
70 BOOST_THREAD_DCL_MOVABLE(X
)
78 int throw_runtime_error()
80 throw std::runtime_error("42");
83 void set_promise_thread(boost::promise
<int>* p
)
91 void set_promise_exception_thread(boost::promise
<int>* p
)
93 p
->set_exception(boost::copy_exception(my_exception()));
97 BOOST_AUTO_TEST_CASE(test_store_value_from_thread
)
101 boost::promise
<int> pi2
;
103 boost::unique_future
<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2
.get_future()));
105 boost::thread(set_promise_thread
,&pi2
);
111 BOOST_CHECK(fi2
.is_ready());
113 BOOST_CHECK(fi2
.has_value());
115 BOOST_CHECK(!fi2
.has_exception());
117 BOOST_CHECK(fi2
.get_state()==boost::future_state::ready
);
122 BOOST_CHECK(false&&"Exception thrown");
126 BOOST_AUTO_TEST_CASE(test_store_exception
)
129 boost::promise
<int> pi3
;
130 boost::unique_future
<int> fi3(BOOST_THREAD_MAKE_RV_REF(pi3
.get_future()));
131 boost::thread(set_promise_exception_thread
,&pi3
);
142 BOOST_CHECK(fi3
.is_ready());
143 BOOST_CHECK(!fi3
.has_value());
144 BOOST_CHECK(fi3
.has_exception());
145 BOOST_CHECK(fi3
.get_state()==boost::future_state::ready
);
148 BOOST_AUTO_TEST_CASE(test_initial_state
)
151 boost::unique_future
<int> fi
;
152 BOOST_CHECK(!fi
.is_ready());
153 BOOST_CHECK(!fi
.has_value());
154 BOOST_CHECK(!fi
.has_exception());
155 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
163 catch(boost::future_uninitialized
)
169 BOOST_AUTO_TEST_CASE(test_waiting_future
)
172 boost::promise
<int> pi
;
173 boost::unique_future
<int> fi
;
174 fi
=BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
177 BOOST_CHECK(!fi
.is_ready());
178 BOOST_CHECK(!fi
.has_value());
179 BOOST_CHECK(!fi
.has_exception());
180 BOOST_CHECK(fi
.get_state()==boost::future_state::waiting
);
184 BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice
)
187 boost::promise
<int> pi
;
188 BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
195 catch(boost::future_already_retrieved
&)
201 BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state
)
204 boost::promise
<int> pi
;
205 boost::unique_future
<int> fi
;
206 fi
=BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
210 BOOST_CHECK(fi
.is_ready());
211 BOOST_CHECK(fi
.has_value());
212 BOOST_CHECK(!fi
.has_exception());
213 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
216 BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved
)
219 boost::promise
<int> pi
;
220 boost::unique_future
<int> fi
;
221 fi
=BOOST_THREAD_MAKE_RV_REF(pi
.get_future());
226 BOOST_CHECK(i
=fi
.get());
228 BOOST_CHECK(fi
.is_ready());
229 BOOST_CHECK(fi
.has_value());
230 BOOST_CHECK(!fi
.has_exception());
231 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
234 BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved
)
237 // boost::promise<int> pi;
238 // boost::unique_future<int> fi;
239 // fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
244 // BOOST_CHECK(i=fi.get());
245 // BOOST_CHECK(i==42);
246 // BOOST_CHECK(fi.is_ready());
247 // BOOST_CHECK(fi.has_value());
248 // BOOST_CHECK(!fi.has_exception());
249 // BOOST_CHECK(fi.get_state()==boost::future_state::ready);
252 BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting
)
255 boost::packaged_task
<int> pt(make_int
);
256 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
258 BOOST_CHECK(!fi
.is_ready());
259 BOOST_CHECK(!fi
.has_value());
260 BOOST_CHECK(!fi
.has_exception());
261 BOOST_CHECK(fi
.get_state()==boost::future_state::waiting
);
265 BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future
)
268 boost::packaged_task
<int> pt(make_int
);
269 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
274 BOOST_CHECK(fi
.is_ready());
275 BOOST_CHECK(fi
.has_value());
276 BOOST_CHECK(!fi
.has_exception());
277 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
278 BOOST_CHECK(i
=fi
.get());
282 BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws
)
285 boost::packaged_task
<int> pt(make_int
);
293 catch(boost::task_already_started
)
300 BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task
)
303 boost::packaged_task
<int> pt(make_int
);
310 catch(boost::future_already_retrieved
)
316 BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws
)
319 boost::packaged_task
<int> pt(throw_runtime_error
);
320 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
324 BOOST_CHECK(fi
.is_ready());
325 BOOST_CHECK(!fi
.has_value());
326 BOOST_CHECK(fi
.has_exception());
327 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
333 catch(std::exception
&)
339 BOOST_CHECK(!"Unknown exception thrown");
344 BOOST_AUTO_TEST_CASE(test_void_promise
)
347 boost::promise
<void> p
;
348 boost::unique_future
<void> f(BOOST_THREAD_MAKE_RV_REF(p
.get_future()));
350 BOOST_CHECK(f
.is_ready());
351 BOOST_CHECK(f
.has_value());
352 BOOST_CHECK(!f
.has_exception());
353 BOOST_CHECK(f
.get_state()==boost::future_state::ready
);
357 BOOST_AUTO_TEST_CASE(test_reference_promise
)
360 boost::promise
<int&> p
;
361 boost::unique_future
<int&> f(BOOST_THREAD_MAKE_RV_REF(p
.get_future()));
364 BOOST_CHECK(f
.is_ready());
365 BOOST_CHECK(f
.has_value());
366 BOOST_CHECK(!f
.has_exception());
367 BOOST_CHECK(f
.get_state()==boost::future_state::ready
);
368 BOOST_CHECK(&f
.get()==&i
);
374 BOOST_AUTO_TEST_CASE(test_task_returning_void
)
377 boost::packaged_task
<void> pt(do_nothing
);
378 boost::unique_future
<void> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
382 BOOST_CHECK(fi
.is_ready());
383 BOOST_CHECK(fi
.has_value());
384 BOOST_CHECK(!fi
.has_exception());
385 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
388 int global_ref_target
=0;
392 return global_ref_target
;
395 BOOST_AUTO_TEST_CASE(test_task_returning_reference
)
398 boost::packaged_task
<int&> pt(return_ref
);
399 boost::unique_future
<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
403 BOOST_CHECK(fi
.is_ready());
404 BOOST_CHECK(fi
.has_value());
405 BOOST_CHECK(!fi
.has_exception());
406 BOOST_CHECK(fi
.get_state()==boost::future_state::ready
);
408 BOOST_CHECK(&i
==&global_ref_target
);
411 BOOST_AUTO_TEST_CASE(test_shared_future
)
414 boost::packaged_task
<int> pt(make_int
);
415 boost::unique_future
<int> fi
=pt
.get_future();
417 boost::shared_future
<int> sf(::cast_to_rval(fi
));
418 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
423 BOOST_CHECK(sf
.is_ready());
424 BOOST_CHECK(sf
.has_value());
425 BOOST_CHECK(!sf
.has_exception());
426 BOOST_CHECK(sf
.get_state()==boost::future_state::ready
);
427 BOOST_CHECK(i
=sf
.get());
431 BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together
)
434 boost::packaged_task
<int> pt(make_int
);
435 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
437 boost::shared_future
<int> sf(::cast_to_rval(fi
));
438 boost::shared_future
<int> sf2(sf
);
439 boost::shared_future
<int> sf3
;
441 BOOST_CHECK(sf
.get_state()==boost::future_state::waiting
);
442 BOOST_CHECK(sf2
.get_state()==boost::future_state::waiting
);
443 BOOST_CHECK(sf3
.get_state()==boost::future_state::waiting
);
448 BOOST_CHECK(sf
.is_ready());
449 BOOST_CHECK(sf
.has_value());
450 BOOST_CHECK(!sf
.has_exception());
451 BOOST_CHECK(sf
.get_state()==boost::future_state::ready
);
452 BOOST_CHECK(i
=sf
.get());
455 BOOST_CHECK(sf2
.is_ready());
456 BOOST_CHECK(sf2
.has_value());
457 BOOST_CHECK(!sf2
.has_exception());
458 BOOST_CHECK(sf2
.get_state()==boost::future_state::ready
);
459 BOOST_CHECK(i
=sf2
.get());
462 BOOST_CHECK(sf3
.is_ready());
463 BOOST_CHECK(sf3
.has_value());
464 BOOST_CHECK(!sf3
.has_exception());
465 BOOST_CHECK(sf3
.get_state()==boost::future_state::ready
);
466 BOOST_CHECK(i
=sf3
.get());
470 BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future
)
473 boost::packaged_task
<int> pt(make_int
);
474 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
476 boost::shared_future
<int> sf
;
477 sf
=::cast_to_rval(fi
);
478 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
480 BOOST_CHECK(!sf
.is_ready());
481 BOOST_CHECK(!sf
.has_value());
482 BOOST_CHECK(!sf
.has_exception());
483 BOOST_CHECK(sf
.get_state()==boost::future_state::waiting
);
486 BOOST_AUTO_TEST_CASE(test_shared_future_void
)
489 boost::packaged_task
<void> pt(do_nothing
);
490 boost::unique_future
<void> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
492 boost::shared_future
<void> sf(::cast_to_rval(fi
));
493 BOOST_CHECK(fi
.get_state()==boost::future_state::uninitialized
);
497 BOOST_CHECK(sf
.is_ready());
498 BOOST_CHECK(sf
.has_value());
499 BOOST_CHECK(!sf
.has_exception());
500 BOOST_CHECK(sf
.get_state()==boost::future_state::ready
);
504 BOOST_AUTO_TEST_CASE(test_shared_future_ref
)
507 boost::promise
<int&> p
;
508 boost::shared_future
<int&> f(BOOST_THREAD_MAKE_RV_REF(p
.get_future()));
511 BOOST_CHECK(f
.is_ready());
512 BOOST_CHECK(f
.has_value());
513 BOOST_CHECK(!f
.has_exception());
514 BOOST_CHECK(f
.get_state()==boost::future_state::ready
);
515 BOOST_CHECK(&f
.get()==&i
);
518 BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise
)
521 boost::promise
<int> pi
;
522 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
524 boost::promise
<int> pi2(::cast_to_rval(pi
));
525 boost::unique_future
<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
528 BOOST_CHECK(fi
.is_ready());
529 BOOST_CHECK(!fi2
.is_ready());
530 BOOST_CHECK(fi
.get()==3);
532 BOOST_CHECK(fi2
.is_ready());
533 BOOST_CHECK(fi2
.get()==42);
536 BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise
)
539 boost::promise
<void> pi
;
540 boost::unique_future
<void> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
542 boost::promise
<void> pi2(::cast_to_rval(pi
));
543 boost::unique_future
<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
546 BOOST_CHECK(fi
.is_ready());
547 BOOST_CHECK(!fi2
.is_ready());
549 BOOST_CHECK(fi2
.is_ready());
552 BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt
)
555 boost::promise
<X
> pt
;
556 boost::unique_future
<X
> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
560 BOOST_CHECK(res
.i
==42);
563 BOOST_AUTO_TEST_CASE(test_unique_future_for_string
)
566 boost::promise
<std::string
> pt
;
567 boost::unique_future
<std::string
> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
569 pt
.set_value(std::string("hello"));
570 std::string
res(fi
.get());
571 BOOST_CHECK(res
=="hello");
573 boost::promise
<std::string
> pt2
;
574 fi
=BOOST_THREAD_MAKE_RV_REF(pt2
.get_future());
576 std::string
const s
="goodbye";
580 BOOST_CHECK(res
=="goodbye");
582 boost::promise
<std::string
> pt3
;
583 fi
=BOOST_THREAD_MAKE_RV_REF(pt3
.get_future());
585 std::string s2
="foo";
589 BOOST_CHECK(res
=="foo");
592 boost::mutex callback_mutex
;
593 unsigned callback_called
=0;
595 void wait_callback(boost::promise
<int>& pi
)
597 boost::lock_guard
<boost::mutex
> lk(callback_mutex
);
608 void do_nothing_callback(boost::promise
<int>& /*pi*/)
610 boost::lock_guard
<boost::mutex
> lk(callback_mutex
);
614 BOOST_AUTO_TEST_CASE(test_wait_callback
)
618 boost::promise
<int> pi
;
619 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
620 pi
.set_wait_callback(wait_callback
);
622 BOOST_CHECK(callback_called
);
623 BOOST_CHECK(fi
.get()==42);
626 BOOST_CHECK(callback_called
==1);
629 BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait
)
633 boost::promise
<int> pi
;
634 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pi
.get_future()));
635 pi
.set_wait_callback(do_nothing_callback
);
636 bool success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
637 BOOST_CHECK(callback_called
);
638 BOOST_CHECK(!success
);
639 success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
640 BOOST_CHECK(!success
);
641 success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
642 BOOST_CHECK(!success
);
643 BOOST_CHECK(callback_called
==3);
645 success
=fi
.timed_wait(boost::posix_time::milliseconds(10));
646 BOOST_CHECK(success
);
647 BOOST_CHECK(callback_called
==3);
648 BOOST_CHECK(fi
.get()==42);
649 BOOST_CHECK(callback_called
==3);
653 void wait_callback_for_task(boost::packaged_task
<int>& pt
)
656 boost::lock_guard
<boost::mutex
> lk(callback_mutex
);
668 BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task
)
672 boost::packaged_task
<int> pt(make_int
);
673 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
674 pt
.set_wait_callback(wait_callback_for_task
);
676 BOOST_CHECK(callback_called
);
677 BOOST_CHECK(fi
.get()==42);
680 BOOST_CHECK(callback_called
==1);
683 BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved
)
686 boost::packaged_task
<int> pt(make_int
);
688 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
690 BOOST_CHECK(!fi
.is_ready());
692 boost::packaged_task
<int> pt2(::cast_to_rval(pt
));
694 BOOST_CHECK(!fi
.is_ready());
698 BOOST_CHECK(!"Can invoke moved task!");
700 catch(boost::task_moved
&)
704 BOOST_CHECK(!fi
.is_ready());
708 BOOST_CHECK(fi
.is_ready());
711 BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise
)
714 boost::unique_future
<int> f
;
717 boost::promise
<int> p
;
718 f
=BOOST_THREAD_MAKE_RV_REF(p
.get_future());
720 BOOST_CHECK(f
.is_ready());
721 BOOST_CHECK(f
.has_exception());
726 catch(boost::broken_promise
&)
731 BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise
)
734 boost::unique_future
<int> f
;
737 boost::packaged_task
<int> p(make_int
);
738 f
=BOOST_THREAD_MAKE_RV_REF(p
.get_future());
740 BOOST_CHECK(f
.is_ready());
741 BOOST_CHECK(f
.has_exception());
746 catch(boost::broken_promise
&)
751 int make_int_slowly()
753 boost::this_thread::sleep(boost::posix_time::seconds(1));
757 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1
)
760 boost::packaged_task
<int> pt(make_int_slowly
);
761 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
762 boost::packaged_task
<int> pt2(make_int_slowly
);
763 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
765 boost::thread(::cast_to_rval(pt
));
767 unsigned const future
=boost::wait_for_any(f1
,f2
);
769 BOOST_CHECK(future
==0);
770 BOOST_CHECK(f1
.is_ready());
771 BOOST_CHECK(!f2
.is_ready());
772 BOOST_CHECK(f1
.get()==42);
775 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2
)
778 boost::packaged_task
<int> pt(make_int_slowly
);
779 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
780 boost::packaged_task
<int> pt2(make_int_slowly
);
781 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
783 boost::thread(::cast_to_rval(pt2
));
785 unsigned const future
=boost::wait_for_any(f1
,f2
);
787 BOOST_CHECK(future
==1);
788 BOOST_CHECK(!f1
.is_ready());
789 BOOST_CHECK(f2
.is_ready());
790 BOOST_CHECK(f2
.get()==42);
793 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1
)
796 boost::packaged_task
<int> pt(make_int_slowly
);
797 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
798 boost::packaged_task
<int> pt2(make_int_slowly
);
799 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
800 boost::packaged_task
<int> pt3(make_int_slowly
);
801 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
803 boost::thread(::cast_to_rval(pt
));
805 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
);
807 BOOST_CHECK(future
==0);
808 BOOST_CHECK(f1
.is_ready());
809 BOOST_CHECK(!f2
.is_ready());
810 BOOST_CHECK(!f3
.is_ready());
811 BOOST_CHECK(f1
.get()==42);
814 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2
)
817 boost::packaged_task
<int> pt(make_int_slowly
);
818 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
819 boost::packaged_task
<int> pt2(make_int_slowly
);
820 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
821 boost::packaged_task
<int> pt3(make_int_slowly
);
822 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
824 boost::thread(::cast_to_rval(pt2
));
826 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
);
828 BOOST_CHECK(future
==1);
829 BOOST_CHECK(!f1
.is_ready());
830 BOOST_CHECK(f2
.is_ready());
831 BOOST_CHECK(!f3
.is_ready());
832 BOOST_CHECK(f2
.get()==42);
835 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3
)
838 boost::packaged_task
<int> pt(make_int_slowly
);
839 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
840 boost::packaged_task
<int> pt2(make_int_slowly
);
841 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
842 boost::packaged_task
<int> pt3(make_int_slowly
);
843 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
845 boost::thread(::cast_to_rval(pt3
));
847 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
);
849 BOOST_CHECK(future
==2);
850 BOOST_CHECK(!f1
.is_ready());
851 BOOST_CHECK(!f2
.is_ready());
852 BOOST_CHECK(f3
.is_ready());
853 BOOST_CHECK(f3
.get()==42);
856 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1
)
859 boost::packaged_task
<int> pt(make_int_slowly
);
860 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
861 boost::packaged_task
<int> pt2(make_int_slowly
);
862 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
863 boost::packaged_task
<int> pt3(make_int_slowly
);
864 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
865 boost::packaged_task
<int> pt4(make_int_slowly
);
866 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
868 boost::thread(::cast_to_rval(pt
));
870 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
872 BOOST_CHECK(future
==0);
873 BOOST_CHECK(f1
.is_ready());
874 BOOST_CHECK(!f2
.is_ready());
875 BOOST_CHECK(!f3
.is_ready());
876 BOOST_CHECK(!f4
.is_ready());
877 BOOST_CHECK(f1
.get()==42);
880 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2
)
883 boost::packaged_task
<int> pt(make_int_slowly
);
884 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
885 boost::packaged_task
<int> pt2(make_int_slowly
);
886 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
887 boost::packaged_task
<int> pt3(make_int_slowly
);
888 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
889 boost::packaged_task
<int> pt4(make_int_slowly
);
890 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
892 boost::thread(::cast_to_rval(pt2
));
894 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
896 BOOST_CHECK(future
==1);
897 BOOST_CHECK(!f1
.is_ready());
898 BOOST_CHECK(f2
.is_ready());
899 BOOST_CHECK(!f3
.is_ready());
900 BOOST_CHECK(!f4
.is_ready());
901 BOOST_CHECK(f2
.get()==42);
904 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3
)
907 boost::packaged_task
<int> pt(make_int_slowly
);
908 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
909 boost::packaged_task
<int> pt2(make_int_slowly
);
910 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
911 boost::packaged_task
<int> pt3(make_int_slowly
);
912 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
913 boost::packaged_task
<int> pt4(make_int_slowly
);
914 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
916 boost::thread(::cast_to_rval(pt3
));
918 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
920 BOOST_CHECK(future
==2);
921 BOOST_CHECK(!f1
.is_ready());
922 BOOST_CHECK(!f2
.is_ready());
923 BOOST_CHECK(f3
.is_ready());
924 BOOST_CHECK(!f4
.is_ready());
925 BOOST_CHECK(f3
.get()==42);
928 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4
)
931 boost::packaged_task
<int> pt(make_int_slowly
);
932 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
933 boost::packaged_task
<int> pt2(make_int_slowly
);
934 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
935 boost::packaged_task
<int> pt3(make_int_slowly
);
936 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
937 boost::packaged_task
<int> pt4(make_int_slowly
);
938 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
940 boost::thread(::cast_to_rval(pt4
));
942 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
);
944 BOOST_CHECK(future
==3);
945 BOOST_CHECK(!f1
.is_ready());
946 BOOST_CHECK(!f2
.is_ready());
947 BOOST_CHECK(!f3
.is_ready());
948 BOOST_CHECK(f4
.is_ready());
949 BOOST_CHECK(f4
.get()==42);
952 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1
)
955 boost::packaged_task
<int> pt(make_int_slowly
);
956 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
957 boost::packaged_task
<int> pt2(make_int_slowly
);
958 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
959 boost::packaged_task
<int> pt3(make_int_slowly
);
960 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
961 boost::packaged_task
<int> pt4(make_int_slowly
);
962 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
963 boost::packaged_task
<int> pt5(make_int_slowly
);
964 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
966 boost::thread(::cast_to_rval(pt
));
968 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
970 BOOST_CHECK(future
==0);
971 BOOST_CHECK(f1
.is_ready());
972 BOOST_CHECK(!f2
.is_ready());
973 BOOST_CHECK(!f3
.is_ready());
974 BOOST_CHECK(!f4
.is_ready());
975 BOOST_CHECK(!f5
.is_ready());
976 BOOST_CHECK(f1
.get()==42);
979 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2
)
982 boost::packaged_task
<int> pt(make_int_slowly
);
983 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
984 boost::packaged_task
<int> pt2(make_int_slowly
);
985 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
986 boost::packaged_task
<int> pt3(make_int_slowly
);
987 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
988 boost::packaged_task
<int> pt4(make_int_slowly
);
989 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
990 boost::packaged_task
<int> pt5(make_int_slowly
);
991 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
993 boost::thread(::cast_to_rval(pt2
));
995 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
997 BOOST_CHECK(future
==1);
998 BOOST_CHECK(!f1
.is_ready());
999 BOOST_CHECK(f2
.is_ready());
1000 BOOST_CHECK(!f3
.is_ready());
1001 BOOST_CHECK(!f4
.is_ready());
1002 BOOST_CHECK(!f5
.is_ready());
1003 BOOST_CHECK(f2
.get()==42);
1005 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3
)
1008 boost::packaged_task
<int> pt(make_int_slowly
);
1009 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1010 boost::packaged_task
<int> pt2(make_int_slowly
);
1011 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1012 boost::packaged_task
<int> pt3(make_int_slowly
);
1013 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
1014 boost::packaged_task
<int> pt4(make_int_slowly
);
1015 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
1016 boost::packaged_task
<int> pt5(make_int_slowly
);
1017 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
1019 boost::thread(::cast_to_rval(pt3
));
1021 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
1023 BOOST_CHECK(future
==2);
1024 BOOST_CHECK(!f1
.is_ready());
1025 BOOST_CHECK(!f2
.is_ready());
1026 BOOST_CHECK(f3
.is_ready());
1027 BOOST_CHECK(!f4
.is_ready());
1028 BOOST_CHECK(!f5
.is_ready());
1029 BOOST_CHECK(f3
.get()==42);
1031 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4
)
1034 boost::packaged_task
<int> pt(make_int_slowly
);
1035 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1036 boost::packaged_task
<int> pt2(make_int_slowly
);
1037 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1038 boost::packaged_task
<int> pt3(make_int_slowly
);
1039 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
1040 boost::packaged_task
<int> pt4(make_int_slowly
);
1041 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
1042 boost::packaged_task
<int> pt5(make_int_slowly
);
1043 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
1045 boost::thread(::cast_to_rval(pt4
));
1047 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
1049 BOOST_CHECK(future
==3);
1050 BOOST_CHECK(!f1
.is_ready());
1051 BOOST_CHECK(!f2
.is_ready());
1052 BOOST_CHECK(!f3
.is_ready());
1053 BOOST_CHECK(f4
.is_ready());
1054 BOOST_CHECK(!f5
.is_ready());
1055 BOOST_CHECK(f4
.get()==42);
1057 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5
)
1060 boost::packaged_task
<int> pt(make_int_slowly
);
1061 boost::unique_future
<int> f1(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1062 boost::packaged_task
<int> pt2(make_int_slowly
);
1063 boost::unique_future
<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1064 boost::packaged_task
<int> pt3(make_int_slowly
);
1065 boost::unique_future
<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3
.get_future()));
1066 boost::packaged_task
<int> pt4(make_int_slowly
);
1067 boost::unique_future
<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4
.get_future()));
1068 boost::packaged_task
<int> pt5(make_int_slowly
);
1069 boost::unique_future
<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5
.get_future()));
1071 boost::thread(::cast_to_rval(pt5
));
1073 unsigned const future
=boost::wait_for_any(f1
,f2
,f3
,f4
,f5
);
1075 BOOST_CHECK(future
==4);
1076 BOOST_CHECK(!f1
.is_ready());
1077 BOOST_CHECK(!f2
.is_ready());
1078 BOOST_CHECK(!f3
.is_ready());
1079 BOOST_CHECK(!f4
.is_ready());
1080 BOOST_CHECK(f5
.is_ready());
1081 BOOST_CHECK(f5
.get()==42);
1084 BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks
)
1088 boost::packaged_task
<int> pt(make_int_slowly
);
1089 boost::unique_future
<int> fi(BOOST_THREAD_MAKE_RV_REF(pt
.get_future()));
1090 boost::packaged_task
<int> pt2(make_int_slowly
);
1091 boost::unique_future
<int> fi2(BOOST_THREAD_MAKE_RV_REF(pt2
.get_future()));
1092 pt
.set_wait_callback(wait_callback_for_task
);
1094 boost::thread(::cast_to_rval(pt
));
1096 boost::wait_for_any(fi
,fi2
);
1097 BOOST_CHECK(callback_called
==1);
1098 BOOST_CHECK(fi
.get()==42);
1101 BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range
)
1104 unsigned const count
=10;
1105 for(unsigned i
=0;i
<count
;++i
)
1107 boost::packaged_task
<int> tasks
[count
];
1108 boost::unique_future
<int> futures
[count
];
1109 for(unsigned j
=0;j
<count
;++j
)
1111 tasks
[j
]=boost::packaged_task
<int>(make_int_slowly
);
1112 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(tasks
[j
].get_future());
1114 boost::thread(::cast_to_rval(tasks
[i
]));
1116 BOOST_CHECK(boost::wait_for_any(futures
,futures
)==futures
);
1118 boost::unique_future
<int>* const future
=boost::wait_for_any(futures
,futures
+count
);
1120 BOOST_CHECK(future
==(futures
+i
));
1121 for(unsigned j
=0;j
<count
;++j
)
1125 BOOST_CHECK(!futures
[j
].is_ready());
1129 BOOST_CHECK(futures
[j
].is_ready());
1132 BOOST_CHECK(futures
[i
].get()==42);
1136 BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range
)
1139 unsigned const count
=10;
1140 boost::unique_future
<int> futures
[count
];
1141 for(unsigned j
=0;j
<count
;++j
)
1143 boost::packaged_task
<int> task(make_int_slowly
);
1144 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1145 boost::thread(::cast_to_rval(task
));
1148 boost::wait_for_all(futures
,futures
+count
);
1150 for(unsigned j
=0;j
<count
;++j
)
1152 BOOST_CHECK(futures
[j
].is_ready());
1156 BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures
)
1159 unsigned const count
=2;
1160 boost::unique_future
<int> futures
[count
];
1161 for(unsigned j
=0;j
<count
;++j
)
1163 boost::packaged_task
<int> task(make_int_slowly
);
1164 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1165 boost::thread(::cast_to_rval(task
));
1168 boost::wait_for_all(futures
[0],futures
[1]);
1170 for(unsigned j
=0;j
<count
;++j
)
1172 BOOST_CHECK(futures
[j
].is_ready());
1176 BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures
)
1179 unsigned const count
=3;
1180 boost::unique_future
<int> futures
[count
];
1181 for(unsigned j
=0;j
<count
;++j
)
1183 boost::packaged_task
<int> task(make_int_slowly
);
1184 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1185 boost::thread(::cast_to_rval(task
));
1188 boost::wait_for_all(futures
[0],futures
[1],futures
[2]);
1190 for(unsigned j
=0;j
<count
;++j
)
1192 BOOST_CHECK(futures
[j
].is_ready());
1196 BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures
)
1199 unsigned const count
=4;
1200 boost::unique_future
<int> futures
[count
];
1201 for(unsigned j
=0;j
<count
;++j
)
1203 boost::packaged_task
<int> task(make_int_slowly
);
1204 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1205 boost::thread(::cast_to_rval(task
));
1208 boost::wait_for_all(futures
[0],futures
[1],futures
[2],futures
[3]);
1210 for(unsigned j
=0;j
<count
;++j
)
1212 BOOST_CHECK(futures
[j
].is_ready());
1216 BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures
)
1219 unsigned const count
=5;
1220 boost::unique_future
<int> futures
[count
];
1221 for(unsigned j
=0;j
<count
;++j
)
1223 boost::packaged_task
<int> task(make_int_slowly
);
1224 futures
[j
]=BOOST_THREAD_MAKE_RV_REF(task
.get_future());
1225 boost::thread(::cast_to_rval(task
));
1228 boost::wait_for_all(futures
[0],futures
[1],futures
[2],futures
[3],futures
[4]);
1230 for(unsigned j
=0;j
<count
;++j
)
1232 BOOST_CHECK(futures
[j
].is_ready());