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