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>
cast_to_rval(T && 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>
cast_to_rval(T & t)35 boost::rv<T>& cast_to_rval(T& t)
36 {
37 return boost::move(t);
38 }
39 #else
40 template<typename T>
cast_to_rval(T & 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
48 struct X
49 {
50 public:
51 int i;
52
53 BOOST_THREAD_MOVABLE_ONLY(X)
XX54 X():
55 i(42)
56 {}
XX57 X(BOOST_THREAD_RV_REF(X) other):
58 i(BOOST_THREAD_RV(other).i)
59 {
60 BOOST_THREAD_RV(other).i=0;
61 }
operator =X62 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 }
~XX68 ~X()
69 {}
70 };
71 namespace boost {
72 BOOST_THREAD_DCL_MOVABLE(X)
73 }
74
make_int()75 int make_int()
76 {
77 return 42;
78 }
79
throw_runtime_error()80 int throw_runtime_error()
81 {
82 throw std::runtime_error("42");
83 }
84
set_promise_thread(boost::promise<int> * p)85 void set_promise_thread(boost::promise<int>* p)
86 {
87 p->set_value(42);
88 }
89
90 struct my_exception
91 {};
92
set_promise_exception_thread(boost::promise<int> * p)93 void set_promise_exception_thread(boost::promise<int>* p)
94 {
95 p->set_exception(boost::copy_exception(my_exception()));
96 }
97
98
BOOST_AUTO_TEST_CASE(test_store_value_from_thread)99 BOOST_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
BOOST_AUTO_TEST_CASE(test_store_exception)128 BOOST_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
BOOST_AUTO_TEST_CASE(test_initial_state)150 BOOST_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
BOOST_AUTO_TEST_CASE(test_waiting_future)171 BOOST_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
BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)186 BOOST_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
BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)203 BOOST_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
BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)218 BOOST_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
BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)236 BOOST_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
BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)254 BOOST_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
BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)267 BOOST_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
BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)284 BOOST_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
BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)302 BOOST_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
BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)318 BOOST_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
BOOST_AUTO_TEST_CASE(test_void_promise)346 BOOST_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
BOOST_AUTO_TEST_CASE(test_reference_promise)359 BOOST_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
do_nothing()373 void do_nothing()
374 {}
375
BOOST_AUTO_TEST_CASE(test_task_returning_void)376 BOOST_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
390 int global_ref_target=0;
391
return_ref()392 int& return_ref()
393 {
394 return global_ref_target;
395 }
396
BOOST_AUTO_TEST_CASE(test_task_returning_reference)397 BOOST_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
BOOST_AUTO_TEST_CASE(test_shared_future)413 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)433 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)472 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_shared_future_void)488 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_shared_future_ref)506 BOOST_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
BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)520 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)538 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)554 BOOST_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
BOOST_AUTO_TEST_CASE(test_unique_future_for_string)565 BOOST_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
594 boost::mutex callback_mutex;
595 unsigned callback_called=0;
596
wait_callback(boost::promise<int> & pi)597 void 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
do_nothing_callback(boost::promise<int> &)610 void do_nothing_callback(boost::promise<int>& /*pi*/)
611 {
612 boost::lock_guard<boost::mutex> lk(callback_mutex);
613 ++callback_called;
614 }
615
BOOST_AUTO_TEST_CASE(test_wait_callback)616 BOOST_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
BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)631 BOOST_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(boost::posix_time::milliseconds(10));
639 BOOST_CHECK(callback_called);
640 BOOST_CHECK(!success);
641 success=fi.timed_wait(boost::posix_time::milliseconds(10));
642 BOOST_CHECK(!success);
643 success=fi.timed_wait(boost::posix_time::milliseconds(10));
644 BOOST_CHECK(!success);
645 BOOST_CHECK(callback_called==3);
646 pi.set_value(42);
647 success=fi.timed_wait(boost::posix_time::milliseconds(10));
648 BOOST_CHECK(success);
649 BOOST_CHECK(callback_called==3);
650 BOOST_CHECK(fi.get()==42);
651 BOOST_CHECK(callback_called==3);
652 }
653
654
wait_callback_for_task(boost::packaged_task<int> & pt)655 void 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
BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)670 BOOST_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
BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)685 BOOST_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(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
BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)713 BOOST_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
BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)733 BOOST_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
make_int_slowly()753 int make_int_slowly()
754 {
755 boost::this_thread::sleep(boost::posix_time::seconds(1));
756 return 42;
757 }
758
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)759 BOOST_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(pt));
768
769 unsigned const future=boost::wait_for_any(f1,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)777 BOOST_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(pt2));
786
787 unsigned const future=boost::wait_for_any(f1,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)795 BOOST_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(pt));
806
807 unsigned const future=boost::wait_for_any(f1,f2,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)816 BOOST_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(pt2));
827
828 unsigned const future=boost::wait_for_any(f1,f2,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)837 BOOST_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(pt3));
848
849 unsigned const future=boost::wait_for_any(f1,f2,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)858 BOOST_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(pt));
871
872 unsigned const future=boost::wait_for_any(f1,f2,f3,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)882 BOOST_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(pt2));
895
896 unsigned const future=boost::wait_for_any(f1,f2,f3,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)906 BOOST_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(pt3));
919
920 unsigned const future=boost::wait_for_any(f1,f2,f3,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)930 BOOST_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(pt4));
943
944 unsigned const future=boost::wait_for_any(f1,f2,f3,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)954 BOOST_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(pt));
969
970 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)981 BOOST_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(pt2));
996
997 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,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 }
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)1007 BOOST_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(pt3));
1022
1023 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,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 }
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)1033 BOOST_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(pt4));
1048
1049 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,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 }
BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)1059 BOOST_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(pt5));
1074
1075 unsigned const future=boost::wait_for_any(f1,f2,f3,f4,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
BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)1086 BOOST_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(pt));
1097
1098 boost::wait_for_any(fi,fi2);
1099 BOOST_CHECK(callback_called==1);
1100 BOOST_CHECK(fi.get()==42);
1101 }
1102
BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)1103 BOOST_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(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(futures,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
BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)1138 BOOST_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(task));
1148 }
1149
1150 boost::wait_for_all(futures,futures+count);
1151
1152 for(unsigned j=0;j<count;++j)
1153 {
1154 BOOST_CHECK(futures[j].is_ready());
1155 }
1156 }
1157
BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)1158 BOOST_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(task));
1168 }
1169
1170 boost::wait_for_all(futures[0],futures[1]);
1171
1172 for(unsigned j=0;j<count;++j)
1173 {
1174 BOOST_CHECK(futures[j].is_ready());
1175 }
1176 }
1177
BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)1178 BOOST_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(task));
1188 }
1189
1190 boost::wait_for_all(futures[0],futures[1],futures[2]);
1191
1192 for(unsigned j=0;j<count;++j)
1193 {
1194 BOOST_CHECK(futures[j].is_ready());
1195 }
1196 }
1197
BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)1198 BOOST_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(task));
1208 }
1209
1210 boost::wait_for_all(futures[0],futures[1],futures[2],futures[3]);
1211
1212 for(unsigned j=0;j<count;++j)
1213 {
1214 BOOST_CHECK(futures[j].is_ready());
1215 }
1216 }
1217
BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)1218 BOOST_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(task));
1228 }
1229
1230 boost::wait_for_all(futures[0],futures[1],futures[2],futures[3],futures[4]);
1231
1232 for(unsigned j=0;j<count;++j)
1233 {
1234 BOOST_CHECK(futures[j].is_ready());
1235 }
1236 }
1237