test_futures.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  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. #define BOOST_THREAD_VERSION 2
  7. #define BOOST_TEST_MODULE Boost.Threads: futures test suite
  8. #include <boost/thread/thread_only.hpp>
  9. #include <boost/thread/mutex.hpp>
  10. #include <boost/thread/condition.hpp>
  11. #include <boost/thread/future.hpp>
  12. #include <utility>
  13. #include <memory>
  14. #include <string>
  15. #include <iostream>
  16. #include <boost/thread/detail/log.hpp>
  17. #include <boost/test/unit_test.hpp>
  18. #ifdef BOOST_MSVC
  19. # pragma warning(disable: 4267) // conversion from ... to ..., possible loss of data
  20. #endif
  21. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  22. template<typename T>
  23. typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
  24. {
  25. return static_cast<typename boost::remove_reference<T>::type&&>(t);
  26. }
  27. #else
  28. #if defined BOOST_THREAD_USES_MOVE
  29. template<typename T>
  30. boost::rv<T>& cast_to_rval(T& t)
  31. {
  32. return boost::move(t);
  33. }
  34. #else
  35. template<typename T>
  36. boost::detail::thread_move_t<T> cast_to_rval(T& t)
  37. {
  38. return boost::move(t);
  39. }
  40. #endif
  41. #endif
  42. struct X
  43. {
  44. public:
  45. int i;
  46. BOOST_THREAD_MOVABLE_ONLY(X)
  47. X():
  48. i(42)
  49. {}
  50. X(BOOST_THREAD_RV_REF(X) other):
  51. i(BOOST_THREAD_RV(other).i)
  52. {
  53. BOOST_THREAD_RV(other).i=0;
  54. }
  55. X& operator=(BOOST_THREAD_RV_REF(X) other)
  56. {
  57. i=BOOST_THREAD_RV(other).i;
  58. BOOST_THREAD_RV(other).i=0;
  59. return *this;
  60. }
  61. ~X()
  62. {}
  63. };
  64. namespace boost {
  65. BOOST_THREAD_DCL_MOVABLE(X)
  66. }
  67. int make_int()
  68. {
  69. return 42;
  70. }
  71. int throw_runtime_error()
  72. {
  73. throw std::runtime_error("42");
  74. }
  75. void set_promise_thread(boost::promise<int>* p)
  76. {
  77. p->set_value(42);
  78. }
  79. struct my_exception
  80. {};
  81. void set_promise_exception_thread(boost::promise<int>* p)
  82. {
  83. p->set_exception(boost::copy_exception(my_exception()));
  84. }
  85. BOOST_AUTO_TEST_CASE(test_store_value_from_thread)
  86. {
  87. BOOST_DETAIL_THREAD_LOG;
  88. try {
  89. boost::promise<int> pi2;
  90. BOOST_DETAIL_THREAD_LOG;
  91. boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2.get_future()));
  92. BOOST_DETAIL_THREAD_LOG;
  93. boost::thread(set_promise_thread,&pi2);
  94. BOOST_DETAIL_THREAD_LOG;
  95. int j=fi2.get();
  96. BOOST_DETAIL_THREAD_LOG;
  97. BOOST_CHECK(j==42);
  98. BOOST_DETAIL_THREAD_LOG;
  99. BOOST_CHECK(fi2.is_ready());
  100. BOOST_DETAIL_THREAD_LOG;
  101. BOOST_CHECK(fi2.has_value());
  102. BOOST_DETAIL_THREAD_LOG;
  103. BOOST_CHECK(!fi2.has_exception());
  104. BOOST_DETAIL_THREAD_LOG;
  105. BOOST_CHECK(fi2.get_state()==boost::future_state::ready);
  106. BOOST_DETAIL_THREAD_LOG;
  107. }
  108. catch (...)
  109. {
  110. BOOST_CHECK(false&&"Exception thrown");
  111. }
  112. }
  113. BOOST_AUTO_TEST_CASE(test_store_exception)
  114. {
  115. BOOST_DETAIL_THREAD_LOG;
  116. boost::promise<int> pi3;
  117. boost::unique_future<int> fi3(BOOST_THREAD_MAKE_RV_REF(pi3.get_future()));
  118. boost::thread(set_promise_exception_thread,&pi3);
  119. try
  120. {
  121. fi3.get();
  122. BOOST_CHECK(false);
  123. }
  124. catch(my_exception)
  125. {
  126. BOOST_CHECK(true);
  127. }
  128. BOOST_CHECK(fi3.is_ready());
  129. BOOST_CHECK(!fi3.has_value());
  130. BOOST_CHECK(fi3.has_exception());
  131. BOOST_CHECK(fi3.get_state()==boost::future_state::ready);
  132. }
  133. BOOST_AUTO_TEST_CASE(test_initial_state)
  134. {
  135. BOOST_DETAIL_THREAD_LOG;
  136. boost::unique_future<int> fi;
  137. BOOST_CHECK(!fi.is_ready());
  138. BOOST_CHECK(!fi.has_value());
  139. BOOST_CHECK(!fi.has_exception());
  140. BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
  141. int i;
  142. try
  143. {
  144. i=fi.get();
  145. (void)i;
  146. BOOST_CHECK(false);
  147. }
  148. catch(boost::future_uninitialized)
  149. {
  150. BOOST_CHECK(true);
  151. }
  152. }
  153. BOOST_AUTO_TEST_CASE(test_waiting_future)
  154. {
  155. BOOST_DETAIL_THREAD_LOG;
  156. boost::promise<int> pi;
  157. boost::unique_future<int> fi;
  158. fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
  159. int i=0;
  160. BOOST_CHECK(!fi.is_ready());
  161. BOOST_CHECK(!fi.has_value());
  162. BOOST_CHECK(!fi.has_exception());
  163. BOOST_CHECK(fi.get_state()==boost::future_state::waiting);
  164. BOOST_CHECK(i==0);
  165. }
  166. BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)
  167. {
  168. BOOST_DETAIL_THREAD_LOG;
  169. boost::promise<int> pi;
  170. BOOST_THREAD_MAKE_RV_REF(pi.get_future());
  171. try
  172. {
  173. pi.get_future();
  174. BOOST_CHECK(false);
  175. }
  176. catch(boost::future_already_retrieved&)
  177. {
  178. BOOST_CHECK(true);
  179. }
  180. }
  181. BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)
  182. {
  183. BOOST_DETAIL_THREAD_LOG;
  184. boost::promise<int> pi;
  185. boost::unique_future<int> fi;
  186. fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
  187. pi.set_value(42);
  188. BOOST_CHECK(fi.is_ready());
  189. BOOST_CHECK(fi.has_value());
  190. BOOST_CHECK(!fi.has_exception());
  191. BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  192. }
  193. BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)
  194. {
  195. BOOST_DETAIL_THREAD_LOG;
  196. boost::promise<int> pi;
  197. boost::unique_future<int> fi;
  198. fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
  199. pi.set_value(42);
  200. int i=0;
  201. BOOST_CHECK(i=fi.get());
  202. BOOST_CHECK(i==42);
  203. BOOST_CHECK(fi.is_ready());
  204. BOOST_CHECK(fi.has_value());
  205. BOOST_CHECK(!fi.has_exception());
  206. BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  207. }
  208. BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)
  209. {
  210. BOOST_DETAIL_THREAD_LOG;
  211. // boost::promise<int> pi;
  212. // boost::unique_future<int> fi;
  213. // fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
  214. // pi.set_value(42);
  215. // int i=0;
  216. // BOOST_CHECK(i=fi.get());
  217. // BOOST_CHECK(i==42);
  218. // BOOST_CHECK(fi.is_ready());
  219. // BOOST_CHECK(fi.has_value());
  220. // BOOST_CHECK(!fi.has_exception());
  221. // BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  222. }
  223. BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)
  224. {
  225. BOOST_DETAIL_THREAD_LOG;
  226. boost::packaged_task<int> pt(make_int);
  227. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  228. int i=0;
  229. BOOST_CHECK(!fi.is_ready());
  230. BOOST_CHECK(!fi.has_value());
  231. BOOST_CHECK(!fi.has_exception());
  232. BOOST_CHECK(fi.get_state()==boost::future_state::waiting);
  233. BOOST_CHECK(i==0);
  234. }
  235. BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)
  236. {
  237. BOOST_DETAIL_THREAD_LOG;
  238. boost::packaged_task<int> pt(make_int);
  239. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  240. pt();
  241. int i=0;
  242. BOOST_CHECK(fi.is_ready());
  243. BOOST_CHECK(fi.has_value());
  244. BOOST_CHECK(!fi.has_exception());
  245. BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  246. BOOST_CHECK(i=fi.get());
  247. BOOST_CHECK(i==42);
  248. }
  249. BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)
  250. {
  251. BOOST_DETAIL_THREAD_LOG;
  252. boost::packaged_task<int> pt(make_int);
  253. pt();
  254. try
  255. {
  256. pt();
  257. BOOST_CHECK(false);
  258. }
  259. catch(boost::task_already_started)
  260. {
  261. BOOST_CHECK(true);
  262. }
  263. }
  264. BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)
  265. {
  266. BOOST_DETAIL_THREAD_LOG;
  267. boost::packaged_task<int> pt(make_int);
  268. pt.get_future();
  269. try
  270. {
  271. pt.get_future();
  272. BOOST_CHECK(false);
  273. }
  274. catch(boost::future_already_retrieved)
  275. {
  276. BOOST_CHECK(true);
  277. }
  278. }
  279. BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)
  280. {
  281. BOOST_DETAIL_THREAD_LOG;
  282. boost::packaged_task<int> pt(throw_runtime_error);
  283. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  284. pt();
  285. BOOST_CHECK(fi.is_ready());
  286. BOOST_CHECK(!fi.has_value());
  287. BOOST_CHECK(fi.has_exception());
  288. BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  289. try
  290. {
  291. fi.get();
  292. BOOST_CHECK(false);
  293. }
  294. catch(std::exception&)
  295. {
  296. BOOST_CHECK(true);
  297. }
  298. catch(...)
  299. {
  300. BOOST_CHECK(!"Unknown exception thrown");
  301. }
  302. }
  303. BOOST_AUTO_TEST_CASE(test_void_promise)
  304. {
  305. BOOST_DETAIL_THREAD_LOG;
  306. boost::promise<void> p;
  307. boost::unique_future<void> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
  308. p.set_value();
  309. BOOST_CHECK(f.is_ready());
  310. BOOST_CHECK(f.has_value());
  311. BOOST_CHECK(!f.has_exception());
  312. BOOST_CHECK(f.get_state()==boost::future_state::ready);
  313. f.get();
  314. }
  315. BOOST_AUTO_TEST_CASE(test_reference_promise)
  316. {
  317. BOOST_DETAIL_THREAD_LOG;
  318. boost::promise<int&> p;
  319. boost::unique_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
  320. int i=42;
  321. p.set_value(i);
  322. BOOST_CHECK(f.is_ready());
  323. BOOST_CHECK(f.has_value());
  324. BOOST_CHECK(!f.has_exception());
  325. BOOST_CHECK(f.get_state()==boost::future_state::ready);
  326. BOOST_CHECK(&f.get()==&i);
  327. }
  328. void do_nothing()
  329. {}
  330. BOOST_AUTO_TEST_CASE(test_task_returning_void)
  331. {
  332. BOOST_DETAIL_THREAD_LOG;
  333. boost::packaged_task<void> pt(do_nothing);
  334. boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  335. pt();
  336. BOOST_CHECK(fi.is_ready());
  337. BOOST_CHECK(fi.has_value());
  338. BOOST_CHECK(!fi.has_exception());
  339. BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  340. }
  341. int global_ref_target=0;
  342. int& return_ref()
  343. {
  344. return global_ref_target;
  345. }
  346. BOOST_AUTO_TEST_CASE(test_task_returning_reference)
  347. {
  348. BOOST_DETAIL_THREAD_LOG;
  349. boost::packaged_task<int&> pt(return_ref);
  350. boost::unique_future<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  351. pt();
  352. BOOST_CHECK(fi.is_ready());
  353. BOOST_CHECK(fi.has_value());
  354. BOOST_CHECK(!fi.has_exception());
  355. BOOST_CHECK(fi.get_state()==boost::future_state::ready);
  356. int& i=fi.get();
  357. BOOST_CHECK(&i==&global_ref_target);
  358. }
  359. BOOST_AUTO_TEST_CASE(test_shared_future)
  360. {
  361. BOOST_DETAIL_THREAD_LOG;
  362. boost::packaged_task<int> pt(make_int);
  363. boost::unique_future<int> fi=pt.get_future();
  364. boost::shared_future<int> sf(::cast_to_rval(fi));
  365. BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
  366. pt();
  367. int i=0;
  368. BOOST_CHECK(sf.is_ready());
  369. BOOST_CHECK(sf.has_value());
  370. BOOST_CHECK(!sf.has_exception());
  371. BOOST_CHECK(sf.get_state()==boost::future_state::ready);
  372. BOOST_CHECK(i=sf.get());
  373. BOOST_CHECK(i==42);
  374. }
  375. BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)
  376. {
  377. BOOST_DETAIL_THREAD_LOG;
  378. boost::packaged_task<int> pt(make_int);
  379. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  380. boost::shared_future<int> sf(::cast_to_rval(fi));
  381. boost::shared_future<int> sf2(sf);
  382. boost::shared_future<int> sf3;
  383. sf3=sf;
  384. BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
  385. BOOST_CHECK(sf2.get_state()==boost::future_state::waiting);
  386. BOOST_CHECK(sf3.get_state()==boost::future_state::waiting);
  387. pt();
  388. int i=0;
  389. BOOST_CHECK(sf.is_ready());
  390. BOOST_CHECK(sf.has_value());
  391. BOOST_CHECK(!sf.has_exception());
  392. BOOST_CHECK(sf.get_state()==boost::future_state::ready);
  393. BOOST_CHECK(i=sf.get());
  394. BOOST_CHECK(i==42);
  395. i=0;
  396. BOOST_CHECK(sf2.is_ready());
  397. BOOST_CHECK(sf2.has_value());
  398. BOOST_CHECK(!sf2.has_exception());
  399. BOOST_CHECK(sf2.get_state()==boost::future_state::ready);
  400. BOOST_CHECK(i=sf2.get());
  401. BOOST_CHECK(i==42);
  402. i=0;
  403. BOOST_CHECK(sf3.is_ready());
  404. BOOST_CHECK(sf3.has_value());
  405. BOOST_CHECK(!sf3.has_exception());
  406. BOOST_CHECK(sf3.get_state()==boost::future_state::ready);
  407. BOOST_CHECK(i=sf3.get());
  408. BOOST_CHECK(i==42);
  409. }
  410. BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)
  411. {
  412. BOOST_DETAIL_THREAD_LOG;
  413. boost::packaged_task<int> pt(make_int);
  414. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  415. boost::shared_future<int> sf;
  416. sf=::cast_to_rval(fi);
  417. BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
  418. BOOST_CHECK(!sf.is_ready());
  419. BOOST_CHECK(!sf.has_value());
  420. BOOST_CHECK(!sf.has_exception());
  421. BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
  422. }
  423. BOOST_AUTO_TEST_CASE(test_shared_future_void)
  424. {
  425. BOOST_DETAIL_THREAD_LOG;
  426. boost::packaged_task<void> pt(do_nothing);
  427. boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  428. boost::shared_future<void> sf(::cast_to_rval(fi));
  429. BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
  430. pt();
  431. BOOST_CHECK(sf.is_ready());
  432. BOOST_CHECK(sf.has_value());
  433. BOOST_CHECK(!sf.has_exception());
  434. BOOST_CHECK(sf.get_state()==boost::future_state::ready);
  435. sf.get();
  436. }
  437. BOOST_AUTO_TEST_CASE(test_shared_future_ref)
  438. {
  439. BOOST_DETAIL_THREAD_LOG;
  440. boost::promise<int&> p;
  441. boost::shared_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
  442. int i=42;
  443. p.set_value(i);
  444. BOOST_CHECK(f.is_ready());
  445. BOOST_CHECK(f.has_value());
  446. BOOST_CHECK(!f.has_exception());
  447. BOOST_CHECK(f.get_state()==boost::future_state::ready);
  448. BOOST_CHECK(&f.get()==&i);
  449. }
  450. BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)
  451. {
  452. BOOST_DETAIL_THREAD_LOG;
  453. boost::promise<int> pi;
  454. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
  455. boost::promise<int> pi2(::cast_to_rval(pi));
  456. boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
  457. pi2.set_value(3);
  458. BOOST_CHECK(fi.is_ready());
  459. BOOST_CHECK(!fi2.is_ready());
  460. BOOST_CHECK(fi.get()==3);
  461. pi.set_value(42);
  462. BOOST_CHECK(fi2.is_ready());
  463. BOOST_CHECK(fi2.get()==42);
  464. }
  465. BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)
  466. {
  467. BOOST_DETAIL_THREAD_LOG;
  468. boost::promise<void> pi;
  469. boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
  470. boost::promise<void> pi2(::cast_to_rval(pi));
  471. boost::unique_future<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
  472. pi2.set_value();
  473. BOOST_CHECK(fi.is_ready());
  474. BOOST_CHECK(!fi2.is_ready());
  475. pi.set_value();
  476. BOOST_CHECK(fi2.is_ready());
  477. }
  478. BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)
  479. {
  480. BOOST_DETAIL_THREAD_LOG;
  481. boost::promise<X> pt;
  482. boost::unique_future<X> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  483. pt.set_value(X());
  484. X res(fi.get());
  485. BOOST_CHECK(res.i==42);
  486. }
  487. BOOST_AUTO_TEST_CASE(test_unique_future_for_string)
  488. {
  489. BOOST_DETAIL_THREAD_LOG;
  490. boost::promise<std::string> pt;
  491. boost::unique_future<std::string> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  492. pt.set_value(std::string("hello"));
  493. std::string res(fi.get());
  494. BOOST_CHECK(res=="hello");
  495. boost::promise<std::string> pt2;
  496. fi=BOOST_THREAD_MAKE_RV_REF(pt2.get_future());
  497. std::string const s="goodbye";
  498. pt2.set_value(s);
  499. res=fi.get();
  500. BOOST_CHECK(res=="goodbye");
  501. boost::promise<std::string> pt3;
  502. fi=BOOST_THREAD_MAKE_RV_REF(pt3.get_future());
  503. std::string s2="foo";
  504. pt3.set_value(s2);
  505. res=fi.get();
  506. BOOST_CHECK(res=="foo");
  507. }
  508. boost::mutex callback_mutex;
  509. unsigned callback_called=0;
  510. void wait_callback(boost::promise<int>& pi)
  511. {
  512. boost::lock_guard<boost::mutex> lk(callback_mutex);
  513. ++callback_called;
  514. try
  515. {
  516. pi.set_value(42);
  517. }
  518. catch(...)
  519. {
  520. }
  521. }
  522. void do_nothing_callback(boost::promise<int>& /*pi*/)
  523. {
  524. boost::lock_guard<boost::mutex> lk(callback_mutex);
  525. ++callback_called;
  526. }
  527. BOOST_AUTO_TEST_CASE(test_wait_callback)
  528. {
  529. BOOST_DETAIL_THREAD_LOG;
  530. callback_called=0;
  531. boost::promise<int> pi;
  532. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
  533. pi.set_wait_callback(wait_callback);
  534. fi.wait();
  535. BOOST_CHECK(callback_called);
  536. BOOST_CHECK(fi.get()==42);
  537. fi.wait();
  538. fi.wait();
  539. BOOST_CHECK(callback_called==1);
  540. }
  541. BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)
  542. {
  543. BOOST_DETAIL_THREAD_LOG;
  544. callback_called=0;
  545. boost::promise<int> pi;
  546. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
  547. pi.set_wait_callback(do_nothing_callback);
  548. bool success=fi.timed_wait(boost::posix_time::milliseconds(10));
  549. BOOST_CHECK(callback_called);
  550. BOOST_CHECK(!success);
  551. success=fi.timed_wait(boost::posix_time::milliseconds(10));
  552. BOOST_CHECK(!success);
  553. success=fi.timed_wait(boost::posix_time::milliseconds(10));
  554. BOOST_CHECK(!success);
  555. BOOST_CHECK(callback_called==3);
  556. pi.set_value(42);
  557. success=fi.timed_wait(boost::posix_time::milliseconds(10));
  558. BOOST_CHECK(success);
  559. BOOST_CHECK(callback_called==3);
  560. BOOST_CHECK(fi.get()==42);
  561. BOOST_CHECK(callback_called==3);
  562. }
  563. void wait_callback_for_task(boost::packaged_task<int>& pt)
  564. {
  565. BOOST_DETAIL_THREAD_LOG;
  566. boost::lock_guard<boost::mutex> lk(callback_mutex);
  567. ++callback_called;
  568. try
  569. {
  570. pt();
  571. }
  572. catch(...)
  573. {
  574. }
  575. }
  576. BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)
  577. {
  578. BOOST_DETAIL_THREAD_LOG;
  579. callback_called=0;
  580. boost::packaged_task<int> pt(make_int);
  581. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  582. pt.set_wait_callback(wait_callback_for_task);
  583. fi.wait();
  584. BOOST_CHECK(callback_called);
  585. BOOST_CHECK(fi.get()==42);
  586. fi.wait();
  587. fi.wait();
  588. BOOST_CHECK(callback_called==1);
  589. }
  590. BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)
  591. {
  592. BOOST_DETAIL_THREAD_LOG;
  593. boost::packaged_task<int> pt(make_int);
  594. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  595. BOOST_CHECK(!fi.is_ready());
  596. boost::packaged_task<int> pt2(::cast_to_rval(pt));
  597. BOOST_CHECK(!fi.is_ready());
  598. try
  599. {
  600. pt();
  601. BOOST_CHECK(!"Can invoke moved task!");
  602. }
  603. catch(boost::task_moved&)
  604. {
  605. }
  606. BOOST_CHECK(!fi.is_ready());
  607. pt2();
  608. BOOST_CHECK(fi.is_ready());
  609. }
  610. BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)
  611. {
  612. BOOST_DETAIL_THREAD_LOG;
  613. boost::unique_future<int> f;
  614. {
  615. boost::promise<int> p;
  616. f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
  617. }
  618. BOOST_CHECK(f.is_ready());
  619. BOOST_CHECK(f.has_exception());
  620. try
  621. {
  622. f.get();
  623. }
  624. catch(boost::broken_promise&)
  625. {
  626. }
  627. }
  628. BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)
  629. {
  630. BOOST_DETAIL_THREAD_LOG;
  631. boost::unique_future<int> f;
  632. {
  633. boost::packaged_task<int> p(make_int);
  634. f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
  635. }
  636. BOOST_CHECK(f.is_ready());
  637. BOOST_CHECK(f.has_exception());
  638. try
  639. {
  640. f.get();
  641. }
  642. catch(boost::broken_promise&)
  643. {
  644. }
  645. }
  646. int make_int_slowly()
  647. {
  648. boost::this_thread::sleep(boost::posix_time::seconds(1));
  649. return 42;
  650. }
  651. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)
  652. {
  653. BOOST_DETAIL_THREAD_LOG;
  654. boost::packaged_task<int> pt(make_int_slowly);
  655. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  656. boost::packaged_task<int> pt2(make_int_slowly);
  657. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  658. boost::thread(::cast_to_rval(pt));
  659. unsigned const future=boost::wait_for_any(f1,f2);
  660. BOOST_CHECK(future==0);
  661. BOOST_CHECK(f1.is_ready());
  662. BOOST_CHECK(!f2.is_ready());
  663. BOOST_CHECK(f1.get()==42);
  664. }
  665. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)
  666. {
  667. BOOST_DETAIL_THREAD_LOG;
  668. boost::packaged_task<int> pt(make_int_slowly);
  669. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  670. boost::packaged_task<int> pt2(make_int_slowly);
  671. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  672. boost::thread(::cast_to_rval(pt2));
  673. unsigned const future=boost::wait_for_any(f1,f2);
  674. BOOST_CHECK(future==1);
  675. BOOST_CHECK(!f1.is_ready());
  676. BOOST_CHECK(f2.is_ready());
  677. BOOST_CHECK(f2.get()==42);
  678. }
  679. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)
  680. {
  681. BOOST_DETAIL_THREAD_LOG;
  682. boost::packaged_task<int> pt(make_int_slowly);
  683. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  684. boost::packaged_task<int> pt2(make_int_slowly);
  685. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  686. boost::packaged_task<int> pt3(make_int_slowly);
  687. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  688. boost::thread(::cast_to_rval(pt));
  689. unsigned const future=boost::wait_for_any(f1,f2,f3);
  690. BOOST_CHECK(future==0);
  691. BOOST_CHECK(f1.is_ready());
  692. BOOST_CHECK(!f2.is_ready());
  693. BOOST_CHECK(!f3.is_ready());
  694. BOOST_CHECK(f1.get()==42);
  695. }
  696. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)
  697. {
  698. BOOST_DETAIL_THREAD_LOG;
  699. boost::packaged_task<int> pt(make_int_slowly);
  700. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  701. boost::packaged_task<int> pt2(make_int_slowly);
  702. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  703. boost::packaged_task<int> pt3(make_int_slowly);
  704. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  705. boost::thread(::cast_to_rval(pt2));
  706. unsigned const future=boost::wait_for_any(f1,f2,f3);
  707. BOOST_CHECK(future==1);
  708. BOOST_CHECK(!f1.is_ready());
  709. BOOST_CHECK(f2.is_ready());
  710. BOOST_CHECK(!f3.is_ready());
  711. BOOST_CHECK(f2.get()==42);
  712. }
  713. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)
  714. {
  715. BOOST_DETAIL_THREAD_LOG;
  716. boost::packaged_task<int> pt(make_int_slowly);
  717. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  718. boost::packaged_task<int> pt2(make_int_slowly);
  719. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  720. boost::packaged_task<int> pt3(make_int_slowly);
  721. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  722. boost::thread(::cast_to_rval(pt3));
  723. unsigned const future=boost::wait_for_any(f1,f2,f3);
  724. BOOST_CHECK(future==2);
  725. BOOST_CHECK(!f1.is_ready());
  726. BOOST_CHECK(!f2.is_ready());
  727. BOOST_CHECK(f3.is_ready());
  728. BOOST_CHECK(f3.get()==42);
  729. }
  730. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)
  731. {
  732. BOOST_DETAIL_THREAD_LOG;
  733. boost::packaged_task<int> pt(make_int_slowly);
  734. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  735. boost::packaged_task<int> pt2(make_int_slowly);
  736. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  737. boost::packaged_task<int> pt3(make_int_slowly);
  738. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  739. boost::packaged_task<int> pt4(make_int_slowly);
  740. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  741. boost::thread(::cast_to_rval(pt));
  742. unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
  743. BOOST_CHECK(future==0);
  744. BOOST_CHECK(f1.is_ready());
  745. BOOST_CHECK(!f2.is_ready());
  746. BOOST_CHECK(!f3.is_ready());
  747. BOOST_CHECK(!f4.is_ready());
  748. BOOST_CHECK(f1.get()==42);
  749. }
  750. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)
  751. {
  752. BOOST_DETAIL_THREAD_LOG;
  753. boost::packaged_task<int> pt(make_int_slowly);
  754. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  755. boost::packaged_task<int> pt2(make_int_slowly);
  756. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  757. boost::packaged_task<int> pt3(make_int_slowly);
  758. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  759. boost::packaged_task<int> pt4(make_int_slowly);
  760. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  761. boost::thread(::cast_to_rval(pt2));
  762. unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
  763. BOOST_CHECK(future==1);
  764. BOOST_CHECK(!f1.is_ready());
  765. BOOST_CHECK(f2.is_ready());
  766. BOOST_CHECK(!f3.is_ready());
  767. BOOST_CHECK(!f4.is_ready());
  768. BOOST_CHECK(f2.get()==42);
  769. }
  770. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)
  771. {
  772. BOOST_DETAIL_THREAD_LOG;
  773. boost::packaged_task<int> pt(make_int_slowly);
  774. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  775. boost::packaged_task<int> pt2(make_int_slowly);
  776. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  777. boost::packaged_task<int> pt3(make_int_slowly);
  778. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  779. boost::packaged_task<int> pt4(make_int_slowly);
  780. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  781. boost::thread(::cast_to_rval(pt3));
  782. unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
  783. BOOST_CHECK(future==2);
  784. BOOST_CHECK(!f1.is_ready());
  785. BOOST_CHECK(!f2.is_ready());
  786. BOOST_CHECK(f3.is_ready());
  787. BOOST_CHECK(!f4.is_ready());
  788. BOOST_CHECK(f3.get()==42);
  789. }
  790. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)
  791. {
  792. BOOST_DETAIL_THREAD_LOG;
  793. boost::packaged_task<int> pt(make_int_slowly);
  794. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  795. boost::packaged_task<int> pt2(make_int_slowly);
  796. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  797. boost::packaged_task<int> pt3(make_int_slowly);
  798. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  799. boost::packaged_task<int> pt4(make_int_slowly);
  800. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  801. boost::thread(::cast_to_rval(pt4));
  802. unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
  803. BOOST_CHECK(future==3);
  804. BOOST_CHECK(!f1.is_ready());
  805. BOOST_CHECK(!f2.is_ready());
  806. BOOST_CHECK(!f3.is_ready());
  807. BOOST_CHECK(f4.is_ready());
  808. BOOST_CHECK(f4.get()==42);
  809. }
  810. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)
  811. {
  812. BOOST_DETAIL_THREAD_LOG;
  813. boost::packaged_task<int> pt(make_int_slowly);
  814. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  815. boost::packaged_task<int> pt2(make_int_slowly);
  816. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  817. boost::packaged_task<int> pt3(make_int_slowly);
  818. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  819. boost::packaged_task<int> pt4(make_int_slowly);
  820. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  821. boost::packaged_task<int> pt5(make_int_slowly);
  822. boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
  823. boost::thread(::cast_to_rval(pt));
  824. unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
  825. BOOST_CHECK(future==0);
  826. BOOST_CHECK(f1.is_ready());
  827. BOOST_CHECK(!f2.is_ready());
  828. BOOST_CHECK(!f3.is_ready());
  829. BOOST_CHECK(!f4.is_ready());
  830. BOOST_CHECK(!f5.is_ready());
  831. BOOST_CHECK(f1.get()==42);
  832. }
  833. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)
  834. {
  835. BOOST_DETAIL_THREAD_LOG;
  836. boost::packaged_task<int> pt(make_int_slowly);
  837. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  838. boost::packaged_task<int> pt2(make_int_slowly);
  839. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  840. boost::packaged_task<int> pt3(make_int_slowly);
  841. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  842. boost::packaged_task<int> pt4(make_int_slowly);
  843. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  844. boost::packaged_task<int> pt5(make_int_slowly);
  845. boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
  846. boost::thread(::cast_to_rval(pt2));
  847. unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
  848. BOOST_CHECK(future==1);
  849. BOOST_CHECK(!f1.is_ready());
  850. BOOST_CHECK(f2.is_ready());
  851. BOOST_CHECK(!f3.is_ready());
  852. BOOST_CHECK(!f4.is_ready());
  853. BOOST_CHECK(!f5.is_ready());
  854. BOOST_CHECK(f2.get()==42);
  855. }
  856. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)
  857. {
  858. BOOST_DETAIL_THREAD_LOG;
  859. boost::packaged_task<int> pt(make_int_slowly);
  860. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  861. boost::packaged_task<int> pt2(make_int_slowly);
  862. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  863. boost::packaged_task<int> pt3(make_int_slowly);
  864. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  865. boost::packaged_task<int> pt4(make_int_slowly);
  866. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  867. boost::packaged_task<int> pt5(make_int_slowly);
  868. boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
  869. boost::thread(::cast_to_rval(pt3));
  870. unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
  871. BOOST_CHECK(future==2);
  872. BOOST_CHECK(!f1.is_ready());
  873. BOOST_CHECK(!f2.is_ready());
  874. BOOST_CHECK(f3.is_ready());
  875. BOOST_CHECK(!f4.is_ready());
  876. BOOST_CHECK(!f5.is_ready());
  877. BOOST_CHECK(f3.get()==42);
  878. }
  879. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)
  880. {
  881. BOOST_DETAIL_THREAD_LOG;
  882. boost::packaged_task<int> pt(make_int_slowly);
  883. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  884. boost::packaged_task<int> pt2(make_int_slowly);
  885. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  886. boost::packaged_task<int> pt3(make_int_slowly);
  887. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  888. boost::packaged_task<int> pt4(make_int_slowly);
  889. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  890. boost::packaged_task<int> pt5(make_int_slowly);
  891. boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
  892. boost::thread(::cast_to_rval(pt4));
  893. unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
  894. BOOST_CHECK(future==3);
  895. BOOST_CHECK(!f1.is_ready());
  896. BOOST_CHECK(!f2.is_ready());
  897. BOOST_CHECK(!f3.is_ready());
  898. BOOST_CHECK(f4.is_ready());
  899. BOOST_CHECK(!f5.is_ready());
  900. BOOST_CHECK(f4.get()==42);
  901. }
  902. BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)
  903. {
  904. BOOST_DETAIL_THREAD_LOG;
  905. boost::packaged_task<int> pt(make_int_slowly);
  906. boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  907. boost::packaged_task<int> pt2(make_int_slowly);
  908. boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  909. boost::packaged_task<int> pt3(make_int_slowly);
  910. boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
  911. boost::packaged_task<int> pt4(make_int_slowly);
  912. boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
  913. boost::packaged_task<int> pt5(make_int_slowly);
  914. boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
  915. boost::thread(::cast_to_rval(pt5));
  916. unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
  917. BOOST_CHECK(future==4);
  918. BOOST_CHECK(!f1.is_ready());
  919. BOOST_CHECK(!f2.is_ready());
  920. BOOST_CHECK(!f3.is_ready());
  921. BOOST_CHECK(!f4.is_ready());
  922. BOOST_CHECK(f5.is_ready());
  923. BOOST_CHECK(f5.get()==42);
  924. }
  925. BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)
  926. {
  927. BOOST_DETAIL_THREAD_LOG;
  928. callback_called=0;
  929. boost::packaged_task<int> pt(make_int_slowly);
  930. boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
  931. boost::packaged_task<int> pt2(make_int_slowly);
  932. boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
  933. pt.set_wait_callback(wait_callback_for_task);
  934. boost::thread(::cast_to_rval(pt));
  935. boost::wait_for_any(fi,fi2);
  936. BOOST_CHECK(callback_called==1);
  937. BOOST_CHECK(fi.get()==42);
  938. }
  939. BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)
  940. {
  941. BOOST_DETAIL_THREAD_LOG;
  942. unsigned const count=10;
  943. for(unsigned i=0;i<count;++i)
  944. {
  945. boost::packaged_task<int> tasks[count];
  946. boost::unique_future<int> futures[count];
  947. for(unsigned j=0;j<count;++j)
  948. {
  949. tasks[j]=boost::packaged_task<int>(make_int_slowly);
  950. futures[j]=BOOST_THREAD_MAKE_RV_REF(tasks[j].get_future());
  951. }
  952. boost::thread(::cast_to_rval(tasks[i]));
  953. BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
  954. boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
  955. BOOST_CHECK(future==(futures+i));
  956. for(unsigned j=0;j<count;++j)
  957. {
  958. if(j!=i)
  959. {
  960. BOOST_CHECK(!futures[j].is_ready());
  961. }
  962. else
  963. {
  964. BOOST_CHECK(futures[j].is_ready());
  965. }
  966. }
  967. BOOST_CHECK(futures[i].get()==42);
  968. }
  969. }
  970. BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)
  971. {
  972. BOOST_DETAIL_THREAD_LOG;
  973. unsigned const count=10;
  974. boost::unique_future<int> futures[count];
  975. for(unsigned j=0;j<count;++j)
  976. {
  977. boost::packaged_task<int> task(make_int_slowly);
  978. futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
  979. boost::thread(::cast_to_rval(task));
  980. }
  981. boost::wait_for_all(futures,futures+count);
  982. for(unsigned j=0;j<count;++j)
  983. {
  984. BOOST_CHECK(futures[j].is_ready());
  985. }
  986. }
  987. BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)
  988. {
  989. BOOST_DETAIL_THREAD_LOG;
  990. unsigned const count=2;
  991. boost::unique_future<int> futures[count];
  992. for(unsigned j=0;j<count;++j)
  993. {
  994. boost::packaged_task<int> task(make_int_slowly);
  995. futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
  996. boost::thread(::cast_to_rval(task));
  997. }
  998. boost::wait_for_all(futures[0],futures[1]);
  999. for(unsigned j=0;j<count;++j)
  1000. {
  1001. BOOST_CHECK(futures[j].is_ready());
  1002. }
  1003. }
  1004. BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)
  1005. {
  1006. BOOST_DETAIL_THREAD_LOG;
  1007. unsigned const count=3;
  1008. boost::unique_future<int> futures[count];
  1009. for(unsigned j=0;j<count;++j)
  1010. {
  1011. boost::packaged_task<int> task(make_int_slowly);
  1012. futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
  1013. boost::thread(::cast_to_rval(task));
  1014. }
  1015. boost::wait_for_all(futures[0],futures[1],futures[2]);
  1016. for(unsigned j=0;j<count;++j)
  1017. {
  1018. BOOST_CHECK(futures[j].is_ready());
  1019. }
  1020. }
  1021. BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)
  1022. {
  1023. BOOST_DETAIL_THREAD_LOG;
  1024. unsigned const count=4;
  1025. boost::unique_future<int> futures[count];
  1026. for(unsigned j=0;j<count;++j)
  1027. {
  1028. boost::packaged_task<int> task(make_int_slowly);
  1029. futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
  1030. boost::thread(::cast_to_rval(task));
  1031. }
  1032. boost::wait_for_all(futures[0],futures[1],futures[2],futures[3]);
  1033. for(unsigned j=0;j<count;++j)
  1034. {
  1035. BOOST_CHECK(futures[j].is_ready());
  1036. }
  1037. }
  1038. BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)
  1039. {
  1040. BOOST_DETAIL_THREAD_LOG;
  1041. unsigned const count=5;
  1042. boost::unique_future<int> futures[count];
  1043. for(unsigned j=0;j<count;++j)
  1044. {
  1045. boost::packaged_task<int> task(make_int_slowly);
  1046. futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
  1047. boost::thread(::cast_to_rval(task));
  1048. }
  1049. boost::wait_for_all(futures[0],futures[1],futures[2],futures[3],futures[4]);
  1050. for(unsigned j=0;j<count;++j)
  1051. {
  1052. BOOST_CHECK(futures[j].is_ready());
  1053. }
  1054. }