]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/thread/test/test_futures.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / thread / test / test_futures.cpp
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
19 #include <boost/test/unit_test.hpp>
20
21 #define LOG \
22 if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
23
24 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
25 template<typename T>
26 typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
27 {
28 return static_cast<typename boost::remove_reference<T>::type&&>(t);
29 }
30 #else
31 #if defined BOOST_THREAD_USES_MOVE
32 template<typename T>
33 boost::rv<T>& cast_to_rval(T& t)
34 {
35 return boost::move(t);
36 }
37 #else
38 template<typename T>
39 boost::detail::thread_move_t<T> cast_to_rval(T& t)
40 {
41 return boost::move(t);
42 }
43 #endif
44 #endif
45
46 struct X
47 {
48 public:
49 int i;
50
51 BOOST_THREAD_MOVABLE_ONLY(X)
52 X():
53 i(42)
54 {}
55 X(BOOST_THREAD_RV_REF(X) other):
56 i(BOOST_THREAD_RV(other).i)
57 {
58 BOOST_THREAD_RV(other).i=0;
59 }
60 X& operator=(BOOST_THREAD_RV_REF(X) other)
61 {
62 i=BOOST_THREAD_RV(other).i;
63 BOOST_THREAD_RV(other).i=0;
64 return *this;
65 }
66 ~X()
67 {}
68 };
69 namespace boost {
70 BOOST_THREAD_DCL_MOVABLE(X)
71 }
72
73 int make_int()
74 {
75 return 42;
76 }
77
78 int throw_runtime_error()
79 {
80 throw std::runtime_error("42");
81 }
82
83 void set_promise_thread(boost::promise<int>* p)
84 {
85 p->set_value(42);
86 }
87
88 struct my_exception
89 {};
90
91 void set_promise_exception_thread(boost::promise<int>* p)
92 {
93 p->set_exception(boost::copy_exception(my_exception()));
94 }
95
96
97 BOOST_AUTO_TEST_CASE(test_store_value_from_thread)
98 {
99 LOG;
100 try {
101 boost::promise<int> pi2;
102 LOG;
103 boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2.get_future()));
104 LOG;
105 boost::thread(set_promise_thread,&pi2);
106 LOG;
107 int j=fi2.get();
108 LOG;
109 BOOST_CHECK(j==42);
110 LOG;
111 BOOST_CHECK(fi2.is_ready());
112 LOG;
113 BOOST_CHECK(fi2.has_value());
114 LOG;
115 BOOST_CHECK(!fi2.has_exception());
116 LOG;
117 BOOST_CHECK(fi2.get_state()==boost::future_state::ready);
118 LOG;
119 }
120 catch (...)
121 {
122 BOOST_CHECK(false&&"Exception thrown");
123 }
124 }
125
126 BOOST_AUTO_TEST_CASE(test_store_exception)
127 {
128 LOG;
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);
132 try
133 {
134 fi3.get();
135 BOOST_CHECK(false);
136 }
137 catch(my_exception)
138 {
139 BOOST_CHECK(true);
140 }
141
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);
146 }
147
148 BOOST_AUTO_TEST_CASE(test_initial_state)
149 {
150 LOG;
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);
156 int i;
157 try
158 {
159 i=fi.get();
160 (void)i;
161 BOOST_CHECK(false);
162 }
163 catch(boost::future_uninitialized)
164 {
165 BOOST_CHECK(true);
166 }
167 }
168
169 BOOST_AUTO_TEST_CASE(test_waiting_future)
170 {
171 LOG;
172 boost::promise<int> pi;
173 boost::unique_future<int> fi;
174 fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
175
176 int i=0;
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);
181 BOOST_CHECK(i==0);
182 }
183
184 BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)
185 {
186 LOG;
187 boost::promise<int> pi;
188 BOOST_THREAD_MAKE_RV_REF(pi.get_future());
189
190 try
191 {
192 pi.get_future();
193 BOOST_CHECK(false);
194 }
195 catch(boost::future_already_retrieved&)
196 {
197 BOOST_CHECK(true);
198 }
199 }
200
201 BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)
202 {
203 LOG;
204 boost::promise<int> pi;
205 boost::unique_future<int> fi;
206 fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
207
208 pi.set_value(42);
209
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);
214 }
215
216 BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)
217 {
218 LOG;
219 boost::promise<int> pi;
220 boost::unique_future<int> fi;
221 fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
222
223 pi.set_value(42);
224
225 int i=0;
226 BOOST_CHECK(i=fi.get());
227 BOOST_CHECK(i==42);
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);
232 }
233
234 BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)
235 {
236 LOG;
237 // boost::promise<int> pi;
238 // boost::unique_future<int> fi;
239 // fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
240
241 // pi.set_value(42);
242
243 // int i=0;
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);
250 }
251
252 BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)
253 {
254 LOG;
255 boost::packaged_task<int> pt(make_int);
256 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
257 int i=0;
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);
262 BOOST_CHECK(i==0);
263 }
264
265 BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)
266 {
267 LOG;
268 boost::packaged_task<int> pt(make_int);
269 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
270
271 pt();
272
273 int i=0;
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());
279 BOOST_CHECK(i==42);
280 }
281
282 BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)
283 {
284 LOG;
285 boost::packaged_task<int> pt(make_int);
286
287 pt();
288 try
289 {
290 pt();
291 BOOST_CHECK(false);
292 }
293 catch(boost::task_already_started)
294 {
295 BOOST_CHECK(true);
296 }
297 }
298
299
300 BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)
301 {
302 LOG;
303 boost::packaged_task<int> pt(make_int);
304 pt.get_future();
305 try
306 {
307 pt.get_future();
308 BOOST_CHECK(false);
309 }
310 catch(boost::future_already_retrieved)
311 {
312 BOOST_CHECK(true);
313 }
314 }
315
316 BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)
317 {
318 LOG;
319 boost::packaged_task<int> pt(throw_runtime_error);
320 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
321
322 pt();
323
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);
328 try
329 {
330 fi.get();
331 BOOST_CHECK(false);
332 }
333 catch(std::exception&)
334 {
335 BOOST_CHECK(true);
336 }
337 catch(...)
338 {
339 BOOST_CHECK(!"Unknown exception thrown");
340 }
341
342 }
343
344 BOOST_AUTO_TEST_CASE(test_void_promise)
345 {
346 LOG;
347 boost::promise<void> p;
348 boost::unique_future<void> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
349 p.set_value();
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);
354 f.get();
355 }
356
357 BOOST_AUTO_TEST_CASE(test_reference_promise)
358 {
359 LOG;
360 boost::promise<int&> p;
361 boost::unique_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
362 int i=42;
363 p.set_value(i);
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);
369 }
370
371 void do_nothing()
372 {}
373
374 BOOST_AUTO_TEST_CASE(test_task_returning_void)
375 {
376 LOG;
377 boost::packaged_task<void> pt(do_nothing);
378 boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
379
380 pt();
381
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);
386 }
387
388 int global_ref_target=0;
389
390 int& return_ref()
391 {
392 return global_ref_target;
393 }
394
395 BOOST_AUTO_TEST_CASE(test_task_returning_reference)
396 {
397 LOG;
398 boost::packaged_task<int&> pt(return_ref);
399 boost::unique_future<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
400
401 pt();
402
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);
407 int& i=fi.get();
408 BOOST_CHECK(&i==&global_ref_target);
409 }
410
411 BOOST_AUTO_TEST_CASE(test_shared_future)
412 {
413 LOG;
414 boost::packaged_task<int> pt(make_int);
415 boost::unique_future<int> fi=pt.get_future();
416
417 boost::shared_future<int> sf(::cast_to_rval(fi));
418 BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
419
420 pt();
421
422 int i=0;
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());
428 BOOST_CHECK(i==42);
429 }
430
431 BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)
432 {
433 LOG;
434 boost::packaged_task<int> pt(make_int);
435 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
436
437 boost::shared_future<int> sf(::cast_to_rval(fi));
438 boost::shared_future<int> sf2(sf);
439 boost::shared_future<int> sf3;
440 sf3=sf;
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);
444
445 pt();
446
447 int i=0;
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());
453 BOOST_CHECK(i==42);
454 i=0;
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());
460 BOOST_CHECK(i==42);
461 i=0;
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());
467 BOOST_CHECK(i==42);
468 }
469
470 BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)
471 {
472 LOG;
473 boost::packaged_task<int> pt(make_int);
474 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
475
476 boost::shared_future<int> sf;
477 sf=::cast_to_rval(fi);
478 BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
479
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);
484 }
485
486 BOOST_AUTO_TEST_CASE(test_shared_future_void)
487 {
488 LOG;
489 boost::packaged_task<void> pt(do_nothing);
490 boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
491
492 boost::shared_future<void> sf(::cast_to_rval(fi));
493 BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
494
495 pt();
496
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);
501 sf.get();
502 }
503
504 BOOST_AUTO_TEST_CASE(test_shared_future_ref)
505 {
506 LOG;
507 boost::promise<int&> p;
508 boost::shared_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
509 int i=42;
510 p.set_value(i);
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);
516 }
517
518 BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)
519 {
520 LOG;
521 boost::promise<int> pi;
522 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
523
524 boost::promise<int> pi2(::cast_to_rval(pi));
525 boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
526
527 pi2.set_value(3);
528 BOOST_CHECK(fi.is_ready());
529 BOOST_CHECK(!fi2.is_ready());
530 BOOST_CHECK(fi.get()==3);
531 pi.set_value(42);
532 BOOST_CHECK(fi2.is_ready());
533 BOOST_CHECK(fi2.get()==42);
534 }
535
536 BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)
537 {
538 LOG;
539 boost::promise<void> pi;
540 boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
541
542 boost::promise<void> pi2(::cast_to_rval(pi));
543 boost::unique_future<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
544
545 pi2.set_value();
546 BOOST_CHECK(fi.is_ready());
547 BOOST_CHECK(!fi2.is_ready());
548 pi.set_value();
549 BOOST_CHECK(fi2.is_ready());
550 }
551
552 BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)
553 {
554 LOG;
555 boost::promise<X> pt;
556 boost::unique_future<X> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
557
558 pt.set_value(X());
559 X res(fi.get());
560 BOOST_CHECK(res.i==42);
561 }
562
563 BOOST_AUTO_TEST_CASE(test_unique_future_for_string)
564 {
565 LOG;
566 boost::promise<std::string> pt;
567 boost::unique_future<std::string> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
568
569 pt.set_value(std::string("hello"));
570 std::string res(fi.get());
571 BOOST_CHECK(res=="hello");
572
573 boost::promise<std::string> pt2;
574 fi=BOOST_THREAD_MAKE_RV_REF(pt2.get_future());
575
576 std::string const s="goodbye";
577
578 pt2.set_value(s);
579 res=fi.get();
580 BOOST_CHECK(res=="goodbye");
581
582 boost::promise<std::string> pt3;
583 fi=BOOST_THREAD_MAKE_RV_REF(pt3.get_future());
584
585 std::string s2="foo";
586
587 pt3.set_value(s2);
588 res=fi.get();
589 BOOST_CHECK(res=="foo");
590 }
591
592 boost::mutex callback_mutex;
593 unsigned callback_called=0;
594
595 void wait_callback(boost::promise<int>& pi)
596 {
597 boost::lock_guard<boost::mutex> lk(callback_mutex);
598 ++callback_called;
599 try
600 {
601 pi.set_value(42);
602 }
603 catch(...)
604 {
605 }
606 }
607
608 void do_nothing_callback(boost::promise<int>& /*pi*/)
609 {
610 boost::lock_guard<boost::mutex> lk(callback_mutex);
611 ++callback_called;
612 }
613
614 BOOST_AUTO_TEST_CASE(test_wait_callback)
615 {
616 LOG;
617 callback_called=0;
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);
621 fi.wait();
622 BOOST_CHECK(callback_called);
623 BOOST_CHECK(fi.get()==42);
624 fi.wait();
625 fi.wait();
626 BOOST_CHECK(callback_called==1);
627 }
628
629 BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)
630 {
631 LOG;
632 callback_called=0;
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);
644 pi.set_value(42);
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);
650 }
651
652
653 void wait_callback_for_task(boost::packaged_task<int>& pt)
654 {
655 LOG;
656 boost::lock_guard<boost::mutex> lk(callback_mutex);
657 ++callback_called;
658 try
659 {
660 pt();
661 }
662 catch(...)
663 {
664 }
665 }
666
667
668 BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)
669 {
670 LOG;
671 callback_called=0;
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);
675 fi.wait();
676 BOOST_CHECK(callback_called);
677 BOOST_CHECK(fi.get()==42);
678 fi.wait();
679 fi.wait();
680 BOOST_CHECK(callback_called==1);
681 }
682
683 BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)
684 {
685 LOG;
686 boost::packaged_task<int> pt(make_int);
687
688 boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
689
690 BOOST_CHECK(!fi.is_ready());
691
692 boost::packaged_task<int> pt2(::cast_to_rval(pt));
693
694 BOOST_CHECK(!fi.is_ready());
695 try
696 {
697 pt();
698 BOOST_CHECK(!"Can invoke moved task!");
699 }
700 catch(boost::task_moved&)
701 {
702 }
703
704 BOOST_CHECK(!fi.is_ready());
705
706 pt2();
707
708 BOOST_CHECK(fi.is_ready());
709 }
710
711 BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)
712 {
713 LOG;
714 boost::unique_future<int> f;
715
716 {
717 boost::promise<int> p;
718 f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
719 }
720 BOOST_CHECK(f.is_ready());
721 BOOST_CHECK(f.has_exception());
722 try
723 {
724 f.get();
725 }
726 catch(boost::broken_promise&)
727 {
728 }
729 }
730
731 BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)
732 {
733 LOG;
734 boost::unique_future<int> f;
735
736 {
737 boost::packaged_task<int> p(make_int);
738 f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
739 }
740 BOOST_CHECK(f.is_ready());
741 BOOST_CHECK(f.has_exception());
742 try
743 {
744 f.get();
745 }
746 catch(boost::broken_promise&)
747 {
748 }
749 }
750
751 int make_int_slowly()
752 {
753 boost::this_thread::sleep(boost::posix_time::seconds(1));
754 return 42;
755 }
756
757 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)
758 {
759 LOG;
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()));
764
765 boost::thread(::cast_to_rval(pt));
766
767 unsigned const future=boost::wait_for_any(f1,f2);
768
769 BOOST_CHECK(future==0);
770 BOOST_CHECK(f1.is_ready());
771 BOOST_CHECK(!f2.is_ready());
772 BOOST_CHECK(f1.get()==42);
773 }
774
775 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)
776 {
777 LOG;
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()));
782
783 boost::thread(::cast_to_rval(pt2));
784
785 unsigned const future=boost::wait_for_any(f1,f2);
786
787 BOOST_CHECK(future==1);
788 BOOST_CHECK(!f1.is_ready());
789 BOOST_CHECK(f2.is_ready());
790 BOOST_CHECK(f2.get()==42);
791 }
792
793 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)
794 {
795 LOG;
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()));
802
803 boost::thread(::cast_to_rval(pt));
804
805 unsigned const future=boost::wait_for_any(f1,f2,f3);
806
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);
812 }
813
814 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)
815 {
816 LOG;
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()));
823
824 boost::thread(::cast_to_rval(pt2));
825
826 unsigned const future=boost::wait_for_any(f1,f2,f3);
827
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);
833 }
834
835 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)
836 {
837 LOG;
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()));
844
845 boost::thread(::cast_to_rval(pt3));
846
847 unsigned const future=boost::wait_for_any(f1,f2,f3);
848
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);
854 }
855
856 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)
857 {
858 LOG;
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()));
867
868 boost::thread(::cast_to_rval(pt));
869
870 unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
871
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);
878 }
879
880 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)
881 {
882 LOG;
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()));
891
892 boost::thread(::cast_to_rval(pt2));
893
894 unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
895
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);
902 }
903
904 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)
905 {
906 LOG;
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()));
915
916 boost::thread(::cast_to_rval(pt3));
917
918 unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
919
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);
926 }
927
928 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)
929 {
930 LOG;
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()));
939
940 boost::thread(::cast_to_rval(pt4));
941
942 unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
943
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);
950 }
951
952 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)
953 {
954 LOG;
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()));
965
966 boost::thread(::cast_to_rval(pt));
967
968 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
969
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);
977 }
978
979 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)
980 {
981 LOG;
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()));
992
993 boost::thread(::cast_to_rval(pt2));
994
995 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
996
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);
1004 }
1005 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)
1006 {
1007 LOG;
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()));
1018
1019 boost::thread(::cast_to_rval(pt3));
1020
1021 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
1022
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);
1030 }
1031 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)
1032 {
1033 LOG;
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()));
1044
1045 boost::thread(::cast_to_rval(pt4));
1046
1047 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
1048
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);
1056 }
1057 BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)
1058 {
1059 LOG;
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()));
1070
1071 boost::thread(::cast_to_rval(pt5));
1072
1073 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
1074
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);
1082 }
1083
1084 BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)
1085 {
1086 LOG;
1087 callback_called=0;
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);
1093
1094 boost::thread(::cast_to_rval(pt));
1095
1096 boost::wait_for_any(fi,fi2);
1097 BOOST_CHECK(callback_called==1);
1098 BOOST_CHECK(fi.get()==42);
1099 }
1100
1101 BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)
1102 {
1103 LOG;
1104 unsigned const count=10;
1105 for(unsigned i=0;i<count;++i)
1106 {
1107 boost::packaged_task<int> tasks[count];
1108 boost::unique_future<int> futures[count];
1109 for(unsigned j=0;j<count;++j)
1110 {
1111 tasks[j]=boost::packaged_task<int>(make_int_slowly);
1112 futures[j]=BOOST_THREAD_MAKE_RV_REF(tasks[j].get_future());
1113 }
1114 boost::thread(::cast_to_rval(tasks[i]));
1115
1116 BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
1117
1118 boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
1119
1120 BOOST_CHECK(future==(futures+i));
1121 for(unsigned j=0;j<count;++j)
1122 {
1123 if(j!=i)
1124 {
1125 BOOST_CHECK(!futures[j].is_ready());
1126 }
1127 else
1128 {
1129 BOOST_CHECK(futures[j].is_ready());
1130 }
1131 }
1132 BOOST_CHECK(futures[i].get()==42);
1133 }
1134 }
1135
1136 BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)
1137 {
1138 LOG;
1139 unsigned const count=10;
1140 boost::unique_future<int> futures[count];
1141 for(unsigned j=0;j<count;++j)
1142 {
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));
1146 }
1147
1148 boost::wait_for_all(futures,futures+count);
1149
1150 for(unsigned j=0;j<count;++j)
1151 {
1152 BOOST_CHECK(futures[j].is_ready());
1153 }
1154 }
1155
1156 BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)
1157 {
1158 LOG;
1159 unsigned const count=2;
1160 boost::unique_future<int> futures[count];
1161 for(unsigned j=0;j<count;++j)
1162 {
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));
1166 }
1167
1168 boost::wait_for_all(futures[0],futures[1]);
1169
1170 for(unsigned j=0;j<count;++j)
1171 {
1172 BOOST_CHECK(futures[j].is_ready());
1173 }
1174 }
1175
1176 BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)
1177 {
1178 LOG;
1179 unsigned const count=3;
1180 boost::unique_future<int> futures[count];
1181 for(unsigned j=0;j<count;++j)
1182 {
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));
1186 }
1187
1188 boost::wait_for_all(futures[0],futures[1],futures[2]);
1189
1190 for(unsigned j=0;j<count;++j)
1191 {
1192 BOOST_CHECK(futures[j].is_ready());
1193 }
1194 }
1195
1196 BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)
1197 {
1198 LOG;
1199 unsigned const count=4;
1200 boost::unique_future<int> futures[count];
1201 for(unsigned j=0;j<count;++j)
1202 {
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));
1206 }
1207
1208 boost::wait_for_all(futures[0],futures[1],futures[2],futures[3]);
1209
1210 for(unsigned j=0;j<count;++j)
1211 {
1212 BOOST_CHECK(futures[j].is_ready());
1213 }
1214 }
1215
1216 BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)
1217 {
1218 LOG;
1219 unsigned const count=5;
1220 boost::unique_future<int> futures[count];
1221 for(unsigned j=0;j<count;++j)
1222 {
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));
1226 }
1227
1228 boost::wait_for_all(futures[0],futures[1],futures[2],futures[3],futures[4]);
1229
1230 for(unsigned j=0;j<count;++j)
1231 {
1232 BOOST_CHECK(futures[j].is_ready());
1233 }
1234 }