123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236 |
- // (C) Copyright 2008-10 Anthony Williams
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #define BOOST_THREAD_VERSION 2
- #define BOOST_TEST_MODULE Boost.Threads: futures test suite
- #include <boost/thread/thread_only.hpp>
- #include <boost/thread/mutex.hpp>
- #include <boost/thread/condition.hpp>
- #include <boost/thread/future.hpp>
- #include <utility>
- #include <memory>
- #include <string>
- #include <iostream>
- #include <boost/thread/detail/log.hpp>
- #include <boost/test/unit_test.hpp>
- #ifdef BOOST_MSVC
- # pragma warning(disable: 4267) // conversion from ... to ..., possible loss of data
- #endif
- #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- template<typename T>
- typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
- {
- return static_cast<typename boost::remove_reference<T>::type&&>(t);
- }
- #else
- #if defined BOOST_THREAD_USES_MOVE
- template<typename T>
- boost::rv<T>& cast_to_rval(T& t)
- {
- return boost::move(t);
- }
- #else
- template<typename T>
- boost::detail::thread_move_t<T> cast_to_rval(T& t)
- {
- return boost::move(t);
- }
- #endif
- #endif
- struct X
- {
- public:
- int i;
- BOOST_THREAD_MOVABLE_ONLY(X)
- X():
- i(42)
- {}
- X(BOOST_THREAD_RV_REF(X) other):
- i(BOOST_THREAD_RV(other).i)
- {
- BOOST_THREAD_RV(other).i=0;
- }
- X& operator=(BOOST_THREAD_RV_REF(X) other)
- {
- i=BOOST_THREAD_RV(other).i;
- BOOST_THREAD_RV(other).i=0;
- return *this;
- }
- ~X()
- {}
- };
- namespace boost {
- BOOST_THREAD_DCL_MOVABLE(X)
- }
- int make_int()
- {
- return 42;
- }
- int throw_runtime_error()
- {
- throw std::runtime_error("42");
- }
- void set_promise_thread(boost::promise<int>* p)
- {
- p->set_value(42);
- }
- struct my_exception
- {};
- void set_promise_exception_thread(boost::promise<int>* p)
- {
- p->set_exception(boost::copy_exception(my_exception()));
- }
- BOOST_AUTO_TEST_CASE(test_store_value_from_thread)
- {
- BOOST_DETAIL_THREAD_LOG;
- try {
- boost::promise<int> pi2;
- BOOST_DETAIL_THREAD_LOG;
- boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2.get_future()));
- BOOST_DETAIL_THREAD_LOG;
- boost::thread(set_promise_thread,&pi2);
- BOOST_DETAIL_THREAD_LOG;
- int j=fi2.get();
- BOOST_DETAIL_THREAD_LOG;
- BOOST_CHECK(j==42);
- BOOST_DETAIL_THREAD_LOG;
- BOOST_CHECK(fi2.is_ready());
- BOOST_DETAIL_THREAD_LOG;
- BOOST_CHECK(fi2.has_value());
- BOOST_DETAIL_THREAD_LOG;
- BOOST_CHECK(!fi2.has_exception());
- BOOST_DETAIL_THREAD_LOG;
- BOOST_CHECK(fi2.get_state()==boost::future_state::ready);
- BOOST_DETAIL_THREAD_LOG;
- }
- catch (...)
- {
- BOOST_CHECK(false&&"Exception thrown");
- }
- }
- BOOST_AUTO_TEST_CASE(test_store_exception)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int> pi3;
- boost::unique_future<int> fi3(BOOST_THREAD_MAKE_RV_REF(pi3.get_future()));
- boost::thread(set_promise_exception_thread,&pi3);
- try
- {
- fi3.get();
- BOOST_CHECK(false);
- }
- catch(my_exception)
- {
- BOOST_CHECK(true);
- }
- BOOST_CHECK(fi3.is_ready());
- BOOST_CHECK(!fi3.has_value());
- BOOST_CHECK(fi3.has_exception());
- BOOST_CHECK(fi3.get_state()==boost::future_state::ready);
- }
- BOOST_AUTO_TEST_CASE(test_initial_state)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::unique_future<int> fi;
- BOOST_CHECK(!fi.is_ready());
- BOOST_CHECK(!fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
- int i;
- try
- {
- i=fi.get();
- (void)i;
- BOOST_CHECK(false);
- }
- catch(boost::future_uninitialized)
- {
- BOOST_CHECK(true);
- }
- }
- BOOST_AUTO_TEST_CASE(test_waiting_future)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int> pi;
- boost::unique_future<int> fi;
- fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
- int i=0;
- BOOST_CHECK(!fi.is_ready());
- BOOST_CHECK(!fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::waiting);
- BOOST_CHECK(i==0);
- }
- BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int> pi;
- BOOST_THREAD_MAKE_RV_REF(pi.get_future());
- try
- {
- pi.get_future();
- BOOST_CHECK(false);
- }
- catch(boost::future_already_retrieved&)
- {
- BOOST_CHECK(true);
- }
- }
- BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int> pi;
- boost::unique_future<int> fi;
- fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
- pi.set_value(42);
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- }
- BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int> pi;
- boost::unique_future<int> fi;
- fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
- pi.set_value(42);
- int i=0;
- BOOST_CHECK(i=fi.get());
- BOOST_CHECK(i==42);
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- }
- BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)
- {
- BOOST_DETAIL_THREAD_LOG;
- // boost::promise<int> pi;
- // boost::unique_future<int> fi;
- // fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
- // pi.set_value(42);
- // int i=0;
- // BOOST_CHECK(i=fi.get());
- // BOOST_CHECK(i==42);
- // BOOST_CHECK(fi.is_ready());
- // BOOST_CHECK(fi.has_value());
- // BOOST_CHECK(!fi.has_exception());
- // BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- }
- BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- int i=0;
- BOOST_CHECK(!fi.is_ready());
- BOOST_CHECK(!fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::waiting);
- BOOST_CHECK(i==0);
- }
- BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt();
- int i=0;
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- BOOST_CHECK(i=fi.get());
- BOOST_CHECK(i==42);
- }
- BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- pt();
- try
- {
- pt();
- BOOST_CHECK(false);
- }
- catch(boost::task_already_started)
- {
- BOOST_CHECK(true);
- }
- }
- BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- pt.get_future();
- try
- {
- pt.get_future();
- BOOST_CHECK(false);
- }
- catch(boost::future_already_retrieved)
- {
- BOOST_CHECK(true);
- }
- }
- BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(throw_runtime_error);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt();
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(!fi.has_value());
- BOOST_CHECK(fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- try
- {
- fi.get();
- BOOST_CHECK(false);
- }
- catch(std::exception&)
- {
- BOOST_CHECK(true);
- }
- catch(...)
- {
- BOOST_CHECK(!"Unknown exception thrown");
- }
- }
- BOOST_AUTO_TEST_CASE(test_void_promise)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<void> p;
- boost::unique_future<void> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
- p.set_value();
- BOOST_CHECK(f.is_ready());
- BOOST_CHECK(f.has_value());
- BOOST_CHECK(!f.has_exception());
- BOOST_CHECK(f.get_state()==boost::future_state::ready);
- f.get();
- }
- BOOST_AUTO_TEST_CASE(test_reference_promise)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int&> p;
- boost::unique_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
- int i=42;
- p.set_value(i);
- BOOST_CHECK(f.is_ready());
- BOOST_CHECK(f.has_value());
- BOOST_CHECK(!f.has_exception());
- BOOST_CHECK(f.get_state()==boost::future_state::ready);
- BOOST_CHECK(&f.get()==&i);
- }
- void do_nothing()
- {}
- BOOST_AUTO_TEST_CASE(test_task_returning_void)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<void> pt(do_nothing);
- boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt();
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- }
- int global_ref_target=0;
- int& return_ref()
- {
- return global_ref_target;
- }
- BOOST_AUTO_TEST_CASE(test_task_returning_reference)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int&> pt(return_ref);
- boost::unique_future<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt();
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(fi.has_value());
- BOOST_CHECK(!fi.has_exception());
- BOOST_CHECK(fi.get_state()==boost::future_state::ready);
- int& i=fi.get();
- BOOST_CHECK(&i==&global_ref_target);
- }
- BOOST_AUTO_TEST_CASE(test_shared_future)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
- boost::shared_future<int> sf(::cast_to_rval(fi));
- BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
- pt();
- int i=0;
- BOOST_CHECK(sf.is_ready());
- BOOST_CHECK(sf.has_value());
- BOOST_CHECK(!sf.has_exception());
- BOOST_CHECK(sf.get_state()==boost::future_state::ready);
- BOOST_CHECK(i=sf.get());
- BOOST_CHECK(i==42);
- }
- BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::shared_future<int> sf(::cast_to_rval(fi));
- boost::shared_future<int> sf2(sf);
- boost::shared_future<int> sf3;
- sf3=sf;
- BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
- BOOST_CHECK(sf2.get_state()==boost::future_state::waiting);
- BOOST_CHECK(sf3.get_state()==boost::future_state::waiting);
- pt();
- int i=0;
- BOOST_CHECK(sf.is_ready());
- BOOST_CHECK(sf.has_value());
- BOOST_CHECK(!sf.has_exception());
- BOOST_CHECK(sf.get_state()==boost::future_state::ready);
- BOOST_CHECK(i=sf.get());
- BOOST_CHECK(i==42);
- i=0;
- BOOST_CHECK(sf2.is_ready());
- BOOST_CHECK(sf2.has_value());
- BOOST_CHECK(!sf2.has_exception());
- BOOST_CHECK(sf2.get_state()==boost::future_state::ready);
- BOOST_CHECK(i=sf2.get());
- BOOST_CHECK(i==42);
- i=0;
- BOOST_CHECK(sf3.is_ready());
- BOOST_CHECK(sf3.has_value());
- BOOST_CHECK(!sf3.has_exception());
- BOOST_CHECK(sf3.get_state()==boost::future_state::ready);
- BOOST_CHECK(i=sf3.get());
- BOOST_CHECK(i==42);
- }
- BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::shared_future<int> sf;
- sf=::cast_to_rval(fi);
- BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
- BOOST_CHECK(!sf.is_ready());
- BOOST_CHECK(!sf.has_value());
- BOOST_CHECK(!sf.has_exception());
- BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
- }
- BOOST_AUTO_TEST_CASE(test_shared_future_void)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<void> pt(do_nothing);
- boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::shared_future<void> sf(::cast_to_rval(fi));
- BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
- pt();
- BOOST_CHECK(sf.is_ready());
- BOOST_CHECK(sf.has_value());
- BOOST_CHECK(!sf.has_exception());
- BOOST_CHECK(sf.get_state()==boost::future_state::ready);
- sf.get();
- }
- BOOST_AUTO_TEST_CASE(test_shared_future_ref)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int&> p;
- boost::shared_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
- int i=42;
- p.set_value(i);
- BOOST_CHECK(f.is_ready());
- BOOST_CHECK(f.has_value());
- BOOST_CHECK(!f.has_exception());
- BOOST_CHECK(f.get_state()==boost::future_state::ready);
- BOOST_CHECK(&f.get()==&i);
- }
- BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<int> pi;
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
- boost::promise<int> pi2(::cast_to_rval(pi));
- boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
- pi2.set_value(3);
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(!fi2.is_ready());
- BOOST_CHECK(fi.get()==3);
- pi.set_value(42);
- BOOST_CHECK(fi2.is_ready());
- BOOST_CHECK(fi2.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<void> pi;
- boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
- boost::promise<void> pi2(::cast_to_rval(pi));
- boost::unique_future<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
- pi2.set_value();
- BOOST_CHECK(fi.is_ready());
- BOOST_CHECK(!fi2.is_ready());
- pi.set_value();
- BOOST_CHECK(fi2.is_ready());
- }
- BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<X> pt;
- boost::unique_future<X> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt.set_value(X());
- X res(fi.get());
- BOOST_CHECK(res.i==42);
- }
- BOOST_AUTO_TEST_CASE(test_unique_future_for_string)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::promise<std::string> pt;
- boost::unique_future<std::string> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt.set_value(std::string("hello"));
- std::string res(fi.get());
- BOOST_CHECK(res=="hello");
- boost::promise<std::string> pt2;
- fi=BOOST_THREAD_MAKE_RV_REF(pt2.get_future());
- std::string const s="goodbye";
- pt2.set_value(s);
- res=fi.get();
- BOOST_CHECK(res=="goodbye");
- boost::promise<std::string> pt3;
- fi=BOOST_THREAD_MAKE_RV_REF(pt3.get_future());
- std::string s2="foo";
- pt3.set_value(s2);
- res=fi.get();
- BOOST_CHECK(res=="foo");
- }
- boost::mutex callback_mutex;
- unsigned callback_called=0;
- void wait_callback(boost::promise<int>& pi)
- {
- boost::lock_guard<boost::mutex> lk(callback_mutex);
- ++callback_called;
- try
- {
- pi.set_value(42);
- }
- catch(...)
- {
- }
- }
- void do_nothing_callback(boost::promise<int>& /*pi*/)
- {
- boost::lock_guard<boost::mutex> lk(callback_mutex);
- ++callback_called;
- }
- BOOST_AUTO_TEST_CASE(test_wait_callback)
- {
- BOOST_DETAIL_THREAD_LOG;
- callback_called=0;
- boost::promise<int> pi;
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
- pi.set_wait_callback(wait_callback);
- fi.wait();
- BOOST_CHECK(callback_called);
- BOOST_CHECK(fi.get()==42);
- fi.wait();
- fi.wait();
- BOOST_CHECK(callback_called==1);
- }
- BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)
- {
- BOOST_DETAIL_THREAD_LOG;
- callback_called=0;
- boost::promise<int> pi;
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
- pi.set_wait_callback(do_nothing_callback);
- bool success=fi.timed_wait(boost::posix_time::milliseconds(10));
- BOOST_CHECK(callback_called);
- BOOST_CHECK(!success);
- success=fi.timed_wait(boost::posix_time::milliseconds(10));
- BOOST_CHECK(!success);
- success=fi.timed_wait(boost::posix_time::milliseconds(10));
- BOOST_CHECK(!success);
- BOOST_CHECK(callback_called==3);
- pi.set_value(42);
- success=fi.timed_wait(boost::posix_time::milliseconds(10));
- BOOST_CHECK(success);
- BOOST_CHECK(callback_called==3);
- BOOST_CHECK(fi.get()==42);
- BOOST_CHECK(callback_called==3);
- }
- void wait_callback_for_task(boost::packaged_task<int>& pt)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::lock_guard<boost::mutex> lk(callback_mutex);
- ++callback_called;
- try
- {
- pt();
- }
- catch(...)
- {
- }
- }
- BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)
- {
- BOOST_DETAIL_THREAD_LOG;
- callback_called=0;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- pt.set_wait_callback(wait_callback_for_task);
- fi.wait();
- BOOST_CHECK(callback_called);
- BOOST_CHECK(fi.get()==42);
- fi.wait();
- fi.wait();
- BOOST_CHECK(callback_called==1);
- }
- BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- BOOST_CHECK(!fi.is_ready());
- boost::packaged_task<int> pt2(::cast_to_rval(pt));
- BOOST_CHECK(!fi.is_ready());
- try
- {
- pt();
- BOOST_CHECK(!"Can invoke moved task!");
- }
- catch(boost::task_moved&)
- {
- }
- BOOST_CHECK(!fi.is_ready());
- pt2();
- BOOST_CHECK(fi.is_ready());
- }
- BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::unique_future<int> f;
- {
- boost::promise<int> p;
- f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
- }
- BOOST_CHECK(f.is_ready());
- BOOST_CHECK(f.has_exception());
- try
- {
- f.get();
- }
- catch(boost::broken_promise&)
- {
- }
- }
- BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::unique_future<int> f;
- {
- boost::packaged_task<int> p(make_int);
- f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
- }
- BOOST_CHECK(f.is_ready());
- BOOST_CHECK(f.has_exception());
- try
- {
- f.get();
- }
- catch(boost::broken_promise&)
- {
- }
- }
- int make_int_slowly()
- {
- boost::this_thread::sleep(boost::posix_time::seconds(1));
- return 42;
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::thread(::cast_to_rval(pt));
- unsigned const future=boost::wait_for_any(f1,f2);
- BOOST_CHECK(future==0);
- BOOST_CHECK(f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(f1.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::thread(::cast_to_rval(pt2));
- unsigned const future=boost::wait_for_any(f1,f2);
- BOOST_CHECK(future==1);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(f2.is_ready());
- BOOST_CHECK(f2.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::thread(::cast_to_rval(pt));
- unsigned const future=boost::wait_for_any(f1,f2,f3);
- BOOST_CHECK(future==0);
- BOOST_CHECK(f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(f1.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::thread(::cast_to_rval(pt2));
- unsigned const future=boost::wait_for_any(f1,f2,f3);
- BOOST_CHECK(future==1);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(f2.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::thread(::cast_to_rval(pt3));
- unsigned const future=boost::wait_for_any(f1,f2,f3);
- BOOST_CHECK(future==2);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(f3.is_ready());
- BOOST_CHECK(f3.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::thread(::cast_to_rval(pt));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
- BOOST_CHECK(future==0);
- BOOST_CHECK(f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(f1.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::thread(::cast_to_rval(pt2));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
- BOOST_CHECK(future==1);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(f2.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::thread(::cast_to_rval(pt3));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
- BOOST_CHECK(future==2);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(f3.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::thread(::cast_to_rval(pt4));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
- BOOST_CHECK(future==3);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(f4.is_ready());
- BOOST_CHECK(f4.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
- boost::thread(::cast_to_rval(pt));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
- BOOST_CHECK(future==0);
- BOOST_CHECK(f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(!f5.is_ready());
- BOOST_CHECK(f1.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
- boost::thread(::cast_to_rval(pt2));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
- BOOST_CHECK(future==1);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(!f5.is_ready());
- BOOST_CHECK(f2.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
- boost::thread(::cast_to_rval(pt3));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
- BOOST_CHECK(future==2);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(!f5.is_ready());
- BOOST_CHECK(f3.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
- boost::thread(::cast_to_rval(pt4));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
- BOOST_CHECK(future==3);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(f4.is_ready());
- BOOST_CHECK(!f5.is_ready());
- BOOST_CHECK(f4.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)
- {
- BOOST_DETAIL_THREAD_LOG;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
- boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
- boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
- boost::thread(::cast_to_rval(pt5));
- unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
- BOOST_CHECK(future==4);
- BOOST_CHECK(!f1.is_ready());
- BOOST_CHECK(!f2.is_ready());
- BOOST_CHECK(!f3.is_ready());
- BOOST_CHECK(!f4.is_ready());
- BOOST_CHECK(f5.is_ready());
- BOOST_CHECK(f5.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)
- {
- BOOST_DETAIL_THREAD_LOG;
- callback_called=0;
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
- boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
- pt.set_wait_callback(wait_callback_for_task);
- boost::thread(::cast_to_rval(pt));
- boost::wait_for_any(fi,fi2);
- BOOST_CHECK(callback_called==1);
- BOOST_CHECK(fi.get()==42);
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)
- {
- BOOST_DETAIL_THREAD_LOG;
- unsigned const count=10;
- for(unsigned i=0;i<count;++i)
- {
- boost::packaged_task<int> tasks[count];
- boost::unique_future<int> futures[count];
- for(unsigned j=0;j<count;++j)
- {
- tasks[j]=boost::packaged_task<int>(make_int_slowly);
- futures[j]=BOOST_THREAD_MAKE_RV_REF(tasks[j].get_future());
- }
- boost::thread(::cast_to_rval(tasks[i]));
- BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
- boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
- BOOST_CHECK(future==(futures+i));
- for(unsigned j=0;j<count;++j)
- {
- if(j!=i)
- {
- BOOST_CHECK(!futures[j].is_ready());
- }
- else
- {
- BOOST_CHECK(futures[j].is_ready());
- }
- }
- BOOST_CHECK(futures[i].get()==42);
- }
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)
- {
- BOOST_DETAIL_THREAD_LOG;
- unsigned const count=10;
- boost::unique_future<int> futures[count];
- for(unsigned j=0;j<count;++j)
- {
- boost::packaged_task<int> task(make_int_slowly);
- futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
- boost::thread(::cast_to_rval(task));
- }
- boost::wait_for_all(futures,futures+count);
- for(unsigned j=0;j<count;++j)
- {
- BOOST_CHECK(futures[j].is_ready());
- }
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)
- {
- BOOST_DETAIL_THREAD_LOG;
- unsigned const count=2;
- boost::unique_future<int> futures[count];
- for(unsigned j=0;j<count;++j)
- {
- boost::packaged_task<int> task(make_int_slowly);
- futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
- boost::thread(::cast_to_rval(task));
- }
- boost::wait_for_all(futures[0],futures[1]);
- for(unsigned j=0;j<count;++j)
- {
- BOOST_CHECK(futures[j].is_ready());
- }
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)
- {
- BOOST_DETAIL_THREAD_LOG;
- unsigned const count=3;
- boost::unique_future<int> futures[count];
- for(unsigned j=0;j<count;++j)
- {
- boost::packaged_task<int> task(make_int_slowly);
- futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
- boost::thread(::cast_to_rval(task));
- }
- boost::wait_for_all(futures[0],futures[1],futures[2]);
- for(unsigned j=0;j<count;++j)
- {
- BOOST_CHECK(futures[j].is_ready());
- }
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)
- {
- BOOST_DETAIL_THREAD_LOG;
- unsigned const count=4;
- boost::unique_future<int> futures[count];
- for(unsigned j=0;j<count;++j)
- {
- boost::packaged_task<int> task(make_int_slowly);
- futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
- boost::thread(::cast_to_rval(task));
- }
- boost::wait_for_all(futures[0],futures[1],futures[2],futures[3]);
- for(unsigned j=0;j<count;++j)
- {
- BOOST_CHECK(futures[j].is_ready());
- }
- }
- BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)
- {
- BOOST_DETAIL_THREAD_LOG;
- unsigned const count=5;
- boost::unique_future<int> futures[count];
- for(unsigned j=0;j<count;++j)
- {
- boost::packaged_task<int> task(make_int_slowly);
- futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
- boost::thread(::cast_to_rval(task));
- }
- boost::wait_for_all(futures[0],futures[1],futures[2],futures[3],futures[4]);
- for(unsigned j=0;j<count;++j)
- {
- BOOST_CHECK(futures[j].is_ready());
- }
- }
|