1// (C) Copyright 2008-10 Anthony Williams
2//
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)
6
7#define BOOST_THREAD_VERSION 2
8#define BOOST_TEST_MODULE Boost.Threads: futures test suite
9
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>
14#include <utility>
15#include <memory>
16#include <string>
17#include <iostream>
18#include <boost/thread/detail/log.hpp>
19
20#include <boost/test/unit_test.hpp>
21
22#ifdef BOOST_MSVC
23# pragma warning(disable: 4267) // conversion from ... to ..., possible loss of data
24#endif
25
26#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
27 template<typename T>
28 typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
29 {
30 return static_cast<typename boost::remove_reference<T>::type&&>(t);
31 }
32#else
33#if defined BOOST_THREAD_USES_MOVE
34 template<typename T>
35 boost::rv<T>& cast_to_rval(T& t)
36 {
37 return boost::move(t);
38 }
39#else
40 template<typename T>
41 boost::detail::thread_move_t<T> cast_to_rval(T& t)
42 {
43 return boost::move(t);
44 }
45#endif
46#endif
47
48struct X
49{
50public:
51 int i;
52
53 BOOST_THREAD_MOVABLE_ONLY(X)
54 X():
55 i(42)
56 {}
57 X(BOOST_THREAD_RV_REF(X) other):
58 i(BOOST_THREAD_RV(other).i)
59 {
60 BOOST_THREAD_RV(other).i=0;
61 }
62 X& operator=(BOOST_THREAD_RV_REF(X) other)
63 {
64 i=BOOST_THREAD_RV(other).i;
65 BOOST_THREAD_RV(other).i=0;
66 return *this;
67 }
68 ~X()
69 {}
70};
71namespace boost {
72 BOOST_THREAD_DCL_MOVABLE(X)
73}
74
75int make_int()
76{
77 return 42;
78}
79
80int throw_runtime_error()
81{
82 throw std::runtime_error("42");
83}
84
85void set_promise_thread(boost::promise<int>* p)
86{
87 p->set_value(42);
88}
89
90struct my_exception
91{};
92
93void set_promise_exception_thread(boost::promise<int>* p)
94{
95 p->set_exception(boost::copy_exception(e: my_exception()));
96}
97
98
99BOOST_AUTO_TEST_CASE(test_store_value_from_thread)
100{
101 BOOST_DETAIL_THREAD_LOG;
102 try {
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;
109 int j=fi2.get();
110 BOOST_DETAIL_THREAD_LOG;
111 BOOST_CHECK(j==42);
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;
121 }
122 catch (...)
123 {
124 BOOST_CHECK(false&&"Exception thrown");
125 }
126}
127
128BOOST_AUTO_TEST_CASE(test_store_exception)
129{
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);
134 try
135 {
136 fi3.get();
137 BOOST_CHECK(false);
138 }
139 catch(my_exception)
140 {
141 BOOST_CHECK(true);
142 }
143
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);
148}
149
150BOOST_AUTO_TEST_CASE(test_initial_state)
151{
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);
158 int i;
159 try
160 {
161 i=fi.get();
162 (void)i;
163 BOOST_CHECK(false);
164 }
165 catch(boost::future_uninitialized)
166 {
167 BOOST_CHECK(true);
168 }
169}
170
171BOOST_AUTO_TEST_CASE(test_waiting_future)
172{
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());
177
178 int i=0;
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);
183 BOOST_CHECK(i==0);
184}
185
186BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)
187{
188 BOOST_DETAIL_THREAD_LOG;
189 boost::promise<int> pi;
190 BOOST_THREAD_MAKE_RV_REF(pi.get_future());
191
192 try
193 {
194 pi.get_future();
195 BOOST_CHECK(false);
196 }
197 catch(boost::future_already_retrieved&)
198 {
199 BOOST_CHECK(true);
200 }
201}
202
203BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)
204{
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());
209
210 pi.set_value(42);
211
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);
216}
217
218BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)
219{
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());
224
225 pi.set_value(42);
226
227 int i=0;
228 BOOST_CHECK(i=fi.get());
229 BOOST_CHECK(i==42);
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);
234}
235
236BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)
237{
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());
242
243// pi.set_value(42);
244
245// int i=0;
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);
252}
253
254BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)
255{
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()));
259 int i=0;
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);
264 BOOST_CHECK(i==0);
265}
266
267BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)
268{
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()));
272
273 pt();
274
275 int i=0;
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());
281 BOOST_CHECK(i==42);
282}
283
284BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)
285{
286 BOOST_DETAIL_THREAD_LOG;
287 boost::packaged_task<int> pt(make_int);
288
289 pt();
290 try
291 {
292 pt();
293 BOOST_CHECK(false);
294 }
295 catch(boost::task_already_started)
296 {
297 BOOST_CHECK(true);
298 }
299}
300
301
302BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)
303{
304 BOOST_DETAIL_THREAD_LOG;
305 boost::packaged_task<int> pt(make_int);
306 pt.get_future();
307 try
308 {
309 pt.get_future();
310 BOOST_CHECK(false);
311 }
312 catch(boost::future_already_retrieved)
313 {
314 BOOST_CHECK(true);
315 }
316}
317
318BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)
319{
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()));
323
324 pt();
325
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);
330 try
331 {
332 fi.get();
333 BOOST_CHECK(false);
334 }
335 catch(std::exception&)
336 {
337 BOOST_CHECK(true);
338 }
339 catch(...)
340 {
341 BOOST_CHECK(!"Unknown exception thrown");
342 }
343
344}
345
346BOOST_AUTO_TEST_CASE(test_void_promise)
347{
348 BOOST_DETAIL_THREAD_LOG;
349 boost::promise<void> p;
350 boost::unique_future<void> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
351 p.set_value();
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);
356 f.get();
357}
358
359BOOST_AUTO_TEST_CASE(test_reference_promise)
360{
361 BOOST_DETAIL_THREAD_LOG;
362 boost::promise<int&> p;
363 boost::unique_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
364 int i=42;
365 p.set_value(i);
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);
371}
372
373void do_nothing()
374{}
375
376BOOST_AUTO_TEST_CASE(test_task_returning_void)
377{
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()));
381
382 pt();
383
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);
388}
389
390int global_ref_target=0;
391
392int& return_ref()
393{
394 return global_ref_target;
395}
396
397BOOST_AUTO_TEST_CASE(test_task_returning_reference)
398{
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()));
402
403 pt();
404
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);
409 int& i=fi.get();
410 BOOST_CHECK(&i==&global_ref_target);
411}
412
413BOOST_AUTO_TEST_CASE(test_shared_future)
414{
415 BOOST_DETAIL_THREAD_LOG;
416 boost::packaged_task<int> pt(make_int);
417 boost::unique_future<int> fi=pt.get_future();
418
419 boost::shared_future<int> sf(::cast_to_rval(t&: fi));
420 BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
421
422 pt();
423
424 int i=0;
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());
430 BOOST_CHECK(i==42);
431}
432
433BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)
434{
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()));
438
439 boost::shared_future<int> sf(::cast_to_rval(t&: fi));
440 boost::shared_future<int> sf2(sf);
441 boost::shared_future<int> sf3;
442 sf3=sf;
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);
446
447 pt();
448
449 int i=0;
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());
455 BOOST_CHECK(i==42);
456 i=0;
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());
462 BOOST_CHECK(i==42);
463 i=0;
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());
469 BOOST_CHECK(i==42);
470}
471
472BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)
473{
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()));
477
478 boost::shared_future<int> sf;
479 sf=::cast_to_rval(t&: fi);
480 BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
481
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);
486}
487
488BOOST_AUTO_TEST_CASE(test_shared_future_void)
489{
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()));
493
494 boost::shared_future<void> sf(::cast_to_rval(t&: fi));
495 BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
496
497 pt();
498
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);
503 sf.get();
504}
505
506BOOST_AUTO_TEST_CASE(test_shared_future_ref)
507{
508 BOOST_DETAIL_THREAD_LOG;
509 boost::promise<int&> p;
510 boost::shared_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
511 int i=42;
512 p.set_value(i);
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);
518}
519
520BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)
521{
522 BOOST_DETAIL_THREAD_LOG;
523 boost::promise<int> pi;
524 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
525
526 boost::promise<int> pi2(::cast_to_rval(t&: pi));
527 boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
528
529 pi2.set_value(3);
530 BOOST_CHECK(fi.is_ready());
531 BOOST_CHECK(!fi2.is_ready());
532 BOOST_CHECK(fi.get()==3);
533 pi.set_value(42);
534 BOOST_CHECK(fi2.is_ready());
535 BOOST_CHECK(fi2.get()==42);
536}
537
538BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)
539{
540 BOOST_DETAIL_THREAD_LOG;
541 boost::promise<void> pi;
542 boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
543
544 boost::promise<void> pi2(::cast_to_rval(t&: pi));
545 boost::unique_future<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
546
547 pi2.set_value();
548 BOOST_CHECK(fi.is_ready());
549 BOOST_CHECK(!fi2.is_ready());
550 pi.set_value();
551 BOOST_CHECK(fi2.is_ready());
552}
553
554BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)
555{
556 BOOST_DETAIL_THREAD_LOG;
557 boost::promise<X> pt;
558 boost::unique_future<X> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
559
560 pt.set_value(X());
561 X res(fi.get());
562 BOOST_CHECK(res.i==42);
563}
564
565BOOST_AUTO_TEST_CASE(test_unique_future_for_string)
566{
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()));
570
571 pt.set_value(std::string("hello"));
572 std::string res(fi.get());
573 BOOST_CHECK(res=="hello");
574
575 boost::promise<std::string> pt2;
576 fi=BOOST_THREAD_MAKE_RV_REF(pt2.get_future());
577
578 std::string const s="goodbye";
579
580 pt2.set_value(s);
581 res=fi.get();
582 BOOST_CHECK(res=="goodbye");
583
584 boost::promise<std::string> pt3;
585 fi=BOOST_THREAD_MAKE_RV_REF(pt3.get_future());
586
587 std::string s2="foo";
588
589 pt3.set_value(s2);
590 res=fi.get();
591 BOOST_CHECK(res=="foo");
592}
593
594boost::mutex callback_mutex;
595unsigned callback_called=0;
596
597void wait_callback(boost::promise<int>& pi)
598{
599 boost::lock_guard<boost::mutex> lk(callback_mutex);
600 ++callback_called;
601 try
602 {
603 pi.set_value(42);
604 }
605 catch(...)
606 {
607 }
608}
609
610void do_nothing_callback(boost::promise<int>& /*pi*/)
611{
612 boost::lock_guard<boost::mutex> lk(callback_mutex);
613 ++callback_called;
614}
615
616BOOST_AUTO_TEST_CASE(test_wait_callback)
617{
618 BOOST_DETAIL_THREAD_LOG;
619 callback_called=0;
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);
623 fi.wait();
624 BOOST_CHECK(callback_called);
625 BOOST_CHECK(fi.get()==42);
626 fi.wait();
627 fi.wait();
628 BOOST_CHECK(callback_called==1);
629}
630
631BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)
632{
633 BOOST_DETAIL_THREAD_LOG;
634 callback_called=0;
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(rel_time: boost::posix_time::milliseconds(10));
639 BOOST_CHECK(callback_called);
640 BOOST_CHECK(!success);
641 success=fi.timed_wait(rel_time: boost::posix_time::milliseconds(10));
642 BOOST_CHECK(!success);
643 success=fi.timed_wait(rel_time: boost::posix_time::milliseconds(10));
644 BOOST_CHECK(!success);
645 BOOST_CHECK(callback_called==3);
646 pi.set_value(42);
647 success=fi.timed_wait(rel_time: 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);
652}
653
654
655void wait_callback_for_task(boost::packaged_task<int>& pt)
656{
657 BOOST_DETAIL_THREAD_LOG;
658 boost::lock_guard<boost::mutex> lk(callback_mutex);
659 ++callback_called;
660 try
661 {
662 pt();
663 }
664 catch(...)
665 {
666 }
667}
668
669
670BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)
671{
672 BOOST_DETAIL_THREAD_LOG;
673 callback_called=0;
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);
677 fi.wait();
678 BOOST_CHECK(callback_called);
679 BOOST_CHECK(fi.get()==42);
680 fi.wait();
681 fi.wait();
682 BOOST_CHECK(callback_called==1);
683}
684
685BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)
686{
687 BOOST_DETAIL_THREAD_LOG;
688 boost::packaged_task<int> pt(make_int);
689
690 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
691
692 BOOST_CHECK(!fi.is_ready());
693
694 boost::packaged_task<int> pt2(::cast_to_rval(t&: pt));
695
696 BOOST_CHECK(!fi.is_ready());
697 try
698 {
699 pt();
700 BOOST_CHECK(!"Can invoke moved task!");
701 }
702 catch(boost::task_moved&)
703 {
704 }
705
706 BOOST_CHECK(!fi.is_ready());
707
708 pt2();
709
710 BOOST_CHECK(fi.is_ready());
711}
712
713BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)
714{
715 BOOST_DETAIL_THREAD_LOG;
716 boost::unique_future<int> f;
717
718 {
719 boost::promise<int> p;
720 f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
721 }
722 BOOST_CHECK(f.is_ready());
723 BOOST_CHECK(f.has_exception());
724 try
725 {
726 f.get();
727 }
728 catch(boost::broken_promise&)
729 {
730 }
731}
732
733BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)
734{
735 BOOST_DETAIL_THREAD_LOG;
736 boost::unique_future<int> f;
737
738 {
739 boost::packaged_task<int> p(make_int);
740 f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
741 }
742 BOOST_CHECK(f.is_ready());
743 BOOST_CHECK(f.has_exception());
744 try
745 {
746 f.get();
747 }
748 catch(boost::broken_promise&)
749 {
750 }
751}
752
753int make_int_slowly()
754{
755 boost::this_thread::sleep(rel_time: boost::posix_time::seconds(1));
756 return 42;
757}
758
759BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)
760{
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()));
766
767 boost::thread(::cast_to_rval(t&: pt));
768
769 unsigned const future=boost::wait_for_any(f1,fs&: f2);
770
771 BOOST_CHECK(future==0);
772 BOOST_CHECK(f1.is_ready());
773 BOOST_CHECK(!f2.is_ready());
774 BOOST_CHECK(f1.get()==42);
775}
776
777BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)
778{
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()));
784
785 boost::thread(::cast_to_rval(t&: pt2));
786
787 unsigned const future=boost::wait_for_any(f1,fs&: f2);
788
789 BOOST_CHECK(future==1);
790 BOOST_CHECK(!f1.is_ready());
791 BOOST_CHECK(f2.is_ready());
792 BOOST_CHECK(f2.get()==42);
793}
794
795BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)
796{
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()));
804
805 boost::thread(::cast_to_rval(t&: pt));
806
807 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3);
808
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);
814}
815
816BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)
817{
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()));
825
826 boost::thread(::cast_to_rval(t&: pt2));
827
828 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3);
829
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);
835}
836
837BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)
838{
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()));
846
847 boost::thread(::cast_to_rval(t&: pt3));
848
849 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3);
850
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);
856}
857
858BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)
859{
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()));
869
870 boost::thread(::cast_to_rval(t&: pt));
871
872 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4);
873
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);
880}
881
882BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)
883{
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()));
893
894 boost::thread(::cast_to_rval(t&: pt2));
895
896 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4);
897
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);
904}
905
906BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)
907{
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()));
917
918 boost::thread(::cast_to_rval(t&: pt3));
919
920 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4);
921
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);
928}
929
930BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)
931{
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()));
941
942 boost::thread(::cast_to_rval(t&: pt4));
943
944 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4);
945
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);
952}
953
954BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)
955{
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()));
967
968 boost::thread(::cast_to_rval(t&: pt));
969
970 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4,fs&: f5);
971
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);
979}
980
981BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)
982{
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()));
994
995 boost::thread(::cast_to_rval(t&: pt2));
996
997 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4,fs&: f5);
998
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);
1006}
1007BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)
1008{
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()));
1020
1021 boost::thread(::cast_to_rval(t&: pt3));
1022
1023 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4,fs&: f5);
1024
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);
1032}
1033BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)
1034{
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()));
1046
1047 boost::thread(::cast_to_rval(t&: pt4));
1048
1049 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4,fs&: f5);
1050
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);
1058}
1059BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)
1060{
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()));
1072
1073 boost::thread(::cast_to_rval(t&: pt5));
1074
1075 unsigned const future=boost::wait_for_any(f1,fs&: f2,fs&: f3,fs&: f4,fs&: f5);
1076
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);
1084}
1085
1086BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)
1087{
1088 BOOST_DETAIL_THREAD_LOG;
1089 callback_called=0;
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);
1095
1096 boost::thread(::cast_to_rval(t&: pt));
1097
1098 boost::wait_for_any(f1&: fi,fs&: fi2);
1099 BOOST_CHECK(callback_called==1);
1100 BOOST_CHECK(fi.get()==42);
1101}
1102
1103BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)
1104{
1105 BOOST_DETAIL_THREAD_LOG;
1106 unsigned const count=10;
1107 for(unsigned i=0;i<count;++i)
1108 {
1109 boost::packaged_task<int> tasks[count];
1110 boost::unique_future<int> futures[count];
1111 for(unsigned j=0;j<count;++j)
1112 {
1113 tasks[j]=boost::packaged_task<int>(make_int_slowly);
1114 futures[j]=BOOST_THREAD_MAKE_RV_REF(tasks[j].get_future());
1115 }
1116 boost::thread(::cast_to_rval(t&: tasks[i]));
1117
1118 BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
1119
1120 boost::unique_future<int>* const future=boost::wait_for_any(begin: futures,end: futures+count);
1121
1122 BOOST_CHECK(future==(futures+i));
1123 for(unsigned j=0;j<count;++j)
1124 {
1125 if(j!=i)
1126 {
1127 BOOST_CHECK(!futures[j].is_ready());
1128 }
1129 else
1130 {
1131 BOOST_CHECK(futures[j].is_ready());
1132 }
1133 }
1134 BOOST_CHECK(futures[i].get()==42);
1135 }
1136}
1137
1138BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)
1139{
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)
1144 {
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(t&: task));
1148 }
1149
1150 boost::wait_for_all(begin: futures,end: futures+count);
1151
1152 for(unsigned j=0;j<count;++j)
1153 {
1154 BOOST_CHECK(futures[j].is_ready());
1155 }
1156}
1157
1158BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)
1159{
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)
1164 {
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(t&: task));
1168 }
1169
1170 boost::wait_for_all(f1&: futures[0],fs&: futures[1]);
1171
1172 for(unsigned j=0;j<count;++j)
1173 {
1174 BOOST_CHECK(futures[j].is_ready());
1175 }
1176}
1177
1178BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)
1179{
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)
1184 {
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(t&: task));
1188 }
1189
1190 boost::wait_for_all(f1&: futures[0],fs&: futures[1],fs&: futures[2]);
1191
1192 for(unsigned j=0;j<count;++j)
1193 {
1194 BOOST_CHECK(futures[j].is_ready());
1195 }
1196}
1197
1198BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)
1199{
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)
1204 {
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(t&: task));
1208 }
1209
1210 boost::wait_for_all(f1&: futures[0],fs&: futures[1],fs&: futures[2],fs&: futures[3]);
1211
1212 for(unsigned j=0;j<count;++j)
1213 {
1214 BOOST_CHECK(futures[j].is_ready());
1215 }
1216}
1217
1218BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)
1219{
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)
1224 {
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(t&: task));
1228 }
1229
1230 boost::wait_for_all(f1&: futures[0],fs&: futures[1],fs&: futures[2],fs&: futures[3],fs&: futures[4]);
1231
1232 for(unsigned j=0;j<count;++j)
1233 {
1234 BOOST_CHECK(futures[j].is_ready());
1235 }
1236}
1237

source code of boost/libs/thread/test/test_futures.cpp