]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
b32b8144 | 18 | #include <boost/thread/detail/log.hpp> |
7c673cae FG |
19 | |
20 | #include <boost/test/unit_test.hpp> | |
21 | ||
b32b8144 FG |
22 | #ifdef BOOST_MSVC |
23 | # pragma warning(disable: 4267) // conversion from ... to ..., possible loss of data | |
24 | #endif | |
7c673cae FG |
25 | |
26 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
27 | template<typename T> | |
28 | typename boost::remove_reference<T>::type&& cast_to_rval(T&& t) | |
29 | { | |
30 | return static_cast<typename boost::remove_reference<T>::type&&>(t); | |
31 | } | |
32 | #else | |
33 | #if defined BOOST_THREAD_USES_MOVE | |
34 | template<typename T> | |
35 | boost::rv<T>& cast_to_rval(T& t) | |
36 | { | |
37 | return boost::move(t); | |
38 | } | |
39 | #else | |
40 | template<typename T> | |
41 | boost::detail::thread_move_t<T> cast_to_rval(T& t) | |
42 | { | |
43 | return boost::move(t); | |
44 | } | |
45 | #endif | |
46 | #endif | |
47 | ||
48 | struct X | |
49 | { | |
50 | public: | |
51 | int i; | |
52 | ||
53 | BOOST_THREAD_MOVABLE_ONLY(X) | |
54 | X(): | |
55 | i(42) | |
56 | {} | |
57 | X(BOOST_THREAD_RV_REF(X) other): | |
58 | i(BOOST_THREAD_RV(other).i) | |
59 | { | |
60 | BOOST_THREAD_RV(other).i=0; | |
61 | } | |
62 | X& operator=(BOOST_THREAD_RV_REF(X) other) | |
63 | { | |
64 | i=BOOST_THREAD_RV(other).i; | |
65 | BOOST_THREAD_RV(other).i=0; | |
66 | return *this; | |
67 | } | |
68 | ~X() | |
69 | {} | |
70 | }; | |
71 | namespace boost { | |
72 | BOOST_THREAD_DCL_MOVABLE(X) | |
73 | } | |
74 | ||
75 | int make_int() | |
76 | { | |
77 | return 42; | |
78 | } | |
79 | ||
80 | int throw_runtime_error() | |
81 | { | |
82 | throw std::runtime_error("42"); | |
83 | } | |
84 | ||
85 | void set_promise_thread(boost::promise<int>* p) | |
86 | { | |
87 | p->set_value(42); | |
88 | } | |
89 | ||
90 | struct my_exception | |
91 | {}; | |
92 | ||
93 | void set_promise_exception_thread(boost::promise<int>* p) | |
94 | { | |
95 | p->set_exception(boost::copy_exception(my_exception())); | |
96 | } | |
97 | ||
98 | ||
99 | BOOST_AUTO_TEST_CASE(test_store_value_from_thread) | |
100 | { | |
b32b8144 | 101 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
102 | try { |
103 | boost::promise<int> pi2; | |
b32b8144 | 104 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 105 | boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2.get_future())); |
b32b8144 | 106 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 107 | boost::thread(set_promise_thread,&pi2); |
b32b8144 | 108 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 109 | int j=fi2.get(); |
b32b8144 | 110 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 111 | BOOST_CHECK(j==42); |
b32b8144 | 112 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 113 | BOOST_CHECK(fi2.is_ready()); |
b32b8144 | 114 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 115 | BOOST_CHECK(fi2.has_value()); |
b32b8144 | 116 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 117 | BOOST_CHECK(!fi2.has_exception()); |
b32b8144 | 118 | BOOST_DETAIL_THREAD_LOG; |
7c673cae | 119 | BOOST_CHECK(fi2.get_state()==boost::future_state::ready); |
b32b8144 | 120 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
121 | } |
122 | catch (...) | |
123 | { | |
124 | BOOST_CHECK(false&&"Exception thrown"); | |
125 | } | |
126 | } | |
127 | ||
128 | BOOST_AUTO_TEST_CASE(test_store_exception) | |
129 | { | |
b32b8144 | 130 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
150 | BOOST_AUTO_TEST_CASE(test_initial_state) | |
151 | { | |
b32b8144 | 152 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
171 | BOOST_AUTO_TEST_CASE(test_waiting_future) | |
172 | { | |
b32b8144 | 173 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
186 | BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice) | |
187 | { | |
b32b8144 | 188 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
203 | BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state) | |
204 | { | |
b32b8144 | 205 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
218 | BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved) | |
219 | { | |
b32b8144 | 220 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
236 | BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved) | |
237 | { | |
b32b8144 | 238 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
254 | BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting) | |
255 | { | |
b32b8144 | 256 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
267 | BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future) | |
268 | { | |
b32b8144 | 269 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
284 | BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws) | |
285 | { | |
b32b8144 | 286 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
302 | BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task) | |
303 | { | |
b32b8144 | 304 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
318 | BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws) | |
319 | { | |
b32b8144 | 320 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
346 | BOOST_AUTO_TEST_CASE(test_void_promise) | |
347 | { | |
b32b8144 | 348 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
359 | BOOST_AUTO_TEST_CASE(test_reference_promise) | |
360 | { | |
b32b8144 | 361 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
373 | void do_nothing() | |
374 | {} | |
375 | ||
376 | BOOST_AUTO_TEST_CASE(test_task_returning_void) | |
377 | { | |
b32b8144 | 378 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
392 | int& return_ref() | |
393 | { | |
394 | return global_ref_target; | |
395 | } | |
396 | ||
397 | BOOST_AUTO_TEST_CASE(test_task_returning_reference) | |
398 | { | |
b32b8144 | 399 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
413 | BOOST_AUTO_TEST_CASE(test_shared_future) | |
414 | { | |
b32b8144 | 415 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
433 | BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together) | |
434 | { | |
b32b8144 | 435 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
472 | BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future) | |
473 | { | |
b32b8144 | 474 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
488 | BOOST_AUTO_TEST_CASE(test_shared_future_void) | |
489 | { | |
b32b8144 | 490 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
506 | BOOST_AUTO_TEST_CASE(test_shared_future_ref) | |
507 | { | |
b32b8144 | 508 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
520 | BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise) | |
521 | { | |
b32b8144 | 522 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
538 | BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise) | |
539 | { | |
b32b8144 | 540 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
554 | BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt) | |
555 | { | |
b32b8144 | 556 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
565 | BOOST_AUTO_TEST_CASE(test_unique_future_for_string) | |
566 | { | |
b32b8144 | 567 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
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 | ||
610 | void do_nothing_callback(boost::promise<int>& /*pi*/) | |
611 | { | |
612 | boost::lock_guard<boost::mutex> lk(callback_mutex); | |
613 | ++callback_called; | |
614 | } | |
615 | ||
616 | BOOST_AUTO_TEST_CASE(test_wait_callback) | |
617 | { | |
b32b8144 | 618 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
631 | BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait) | |
632 | { | |
b32b8144 | 633 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
655 | void wait_callback_for_task(boost::packaged_task<int>& pt) | |
656 | { | |
b32b8144 | 657 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
670 | BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task) | |
671 | { | |
b32b8144 | 672 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
685 | BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved) | |
686 | { | |
b32b8144 | 687 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
713 | BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise) | |
714 | { | |
b32b8144 | 715 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
733 | BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise) | |
734 | { | |
b32b8144 | 735 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
753 | int make_int_slowly() | |
754 | { | |
755 | boost::this_thread::sleep(boost::posix_time::seconds(1)); | |
756 | return 42; | |
757 | } | |
758 | ||
759 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1) | |
760 | { | |
b32b8144 | 761 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
777 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2) | |
778 | { | |
b32b8144 | 779 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
795 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1) | |
796 | { | |
b32b8144 | 797 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
816 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2) | |
817 | { | |
b32b8144 | 818 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
837 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3) | |
838 | { | |
b32b8144 | 839 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
858 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1) | |
859 | { | |
b32b8144 | 860 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
882 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2) | |
883 | { | |
b32b8144 | 884 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
906 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3) | |
907 | { | |
b32b8144 | 908 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
930 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4) | |
931 | { | |
b32b8144 | 932 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
954 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1) | |
955 | { | |
b32b8144 | 956 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
981 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2) | |
982 | { | |
b32b8144 | 983 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | } | |
1007 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3) | |
1008 | { | |
b32b8144 | 1009 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | } | |
1033 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4) | |
1034 | { | |
b32b8144 | 1035 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | } | |
1059 | BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5) | |
1060 | { | |
b32b8144 | 1061 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1086 | BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks) | |
1087 | { | |
b32b8144 | 1088 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1103 | BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range) | |
1104 | { | |
b32b8144 | 1105 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1138 | BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range) | |
1139 | { | |
b32b8144 | 1140 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1158 | BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures) | |
1159 | { | |
b32b8144 | 1160 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1178 | BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures) | |
1179 | { | |
b32b8144 | 1180 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1198 | BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures) | |
1199 | { | |
b32b8144 | 1200 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | ||
1218 | BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures) | |
1219 | { | |
b32b8144 | 1220 | BOOST_DETAIL_THREAD_LOG; |
7c673cae FG |
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 | } |