future.hpp 133 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241
  1. // (C) Copyright 2008-10 Anthony Williams
  2. // (C) Copyright 2011-2013 Vicente J. Botet Escriba
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_THREAD_FUTURE_HPP
  8. #define BOOST_THREAD_FUTURE_HPP
  9. #include <boost/thread/detail/config.hpp>
  10. // boost::thread::future requires exception handling
  11. // due to boost::exception::exception_ptr dependency
  12. #ifndef BOOST_NO_EXCEPTIONS
  13. //#include <boost/thread/detail/log.hpp>
  14. #include <boost/detail/scoped_enum_emulation.hpp>
  15. #include <stdexcept>
  16. #include <boost/thread/detail/move.hpp>
  17. #include <boost/thread/detail/async_func.hpp>
  18. #include <boost/thread/thread_time.hpp>
  19. #include <boost/thread/mutex.hpp>
  20. #include <boost/thread/condition_variable.hpp>
  21. #include <boost/thread/lock_algorithms.hpp>
  22. #include <boost/thread/lock_types.hpp>
  23. #include <boost/exception_ptr.hpp>
  24. #include <boost/shared_ptr.hpp>
  25. #include <boost/scoped_ptr.hpp>
  26. #include <boost/type_traits/is_fundamental.hpp>
  27. #include <boost/thread/detail/is_convertible.hpp>
  28. #include <boost/type_traits/remove_reference.hpp>
  29. #include <boost/type_traits/remove_cv.hpp>
  30. #include <boost/type_traits/is_void.hpp>
  31. #include <boost/mpl/if.hpp>
  32. #include <boost/config.hpp>
  33. #include <boost/throw_exception.hpp>
  34. #include <algorithm>
  35. #include <boost/function.hpp>
  36. #include <boost/bind.hpp>
  37. #include <boost/ref.hpp>
  38. #include <boost/scoped_array.hpp>
  39. #include <boost/enable_shared_from_this.hpp>
  40. #include <boost/utility/enable_if.hpp>
  41. #include <list>
  42. #include <boost/next_prior.hpp>
  43. #include <vector>
  44. #include <boost/thread/future_error_code.hpp>
  45. #ifdef BOOST_THREAD_USES_CHRONO
  46. #include <boost/chrono/system_clocks.hpp>
  47. #endif
  48. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  49. #include <boost/thread/detail/memory.hpp>
  50. #endif
  51. #include <boost/utility/result_of.hpp>
  52. #include <boost/thread/thread_only.hpp>
  53. #if defined BOOST_THREAD_PROVIDES_FUTURE
  54. #define BOOST_THREAD_FUTURE future
  55. #else
  56. #define BOOST_THREAD_FUTURE unique_future
  57. #endif
  58. namespace boost
  59. {
  60. //enum class launch
  61. BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch)
  62. {
  63. none = 0,
  64. async = 1,
  65. deferred = 2,
  66. any = async | deferred
  67. }
  68. BOOST_SCOPED_ENUM_DECLARE_END(launch)
  69. //enum class future_status
  70. BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status)
  71. {
  72. ready,
  73. timeout,
  74. deferred
  75. }
  76. BOOST_SCOPED_ENUM_DECLARE_END(future_status)
  77. class BOOST_SYMBOL_VISIBLE future_error
  78. : public std::logic_error
  79. {
  80. system::error_code ec_;
  81. public:
  82. future_error(system::error_code ec)
  83. : logic_error(ec.message()),
  84. ec_(ec)
  85. {
  86. }
  87. const system::error_code& code() const BOOST_NOEXCEPT
  88. {
  89. return ec_;
  90. }
  91. };
  92. class BOOST_SYMBOL_VISIBLE future_uninitialized:
  93. public future_error
  94. {
  95. public:
  96. future_uninitialized() :
  97. future_error(system::make_error_code(future_errc::no_state))
  98. {}
  99. };
  100. class BOOST_SYMBOL_VISIBLE broken_promise:
  101. public future_error
  102. {
  103. public:
  104. broken_promise():
  105. future_error(system::make_error_code(future_errc::broken_promise))
  106. {}
  107. };
  108. class BOOST_SYMBOL_VISIBLE future_already_retrieved:
  109. public future_error
  110. {
  111. public:
  112. future_already_retrieved():
  113. future_error(system::make_error_code(future_errc::future_already_retrieved))
  114. {}
  115. };
  116. class BOOST_SYMBOL_VISIBLE promise_already_satisfied:
  117. public future_error
  118. {
  119. public:
  120. promise_already_satisfied():
  121. future_error(system::make_error_code(future_errc::promise_already_satisfied))
  122. {}
  123. };
  124. class BOOST_SYMBOL_VISIBLE task_already_started:
  125. public future_error
  126. {
  127. public:
  128. task_already_started():
  129. future_error(system::make_error_code(future_errc::promise_already_satisfied))
  130. {}
  131. };
  132. class BOOST_SYMBOL_VISIBLE task_moved:
  133. public future_error
  134. {
  135. public:
  136. task_moved():
  137. future_error(system::make_error_code(future_errc::no_state))
  138. {}
  139. };
  140. class promise_moved:
  141. public future_error
  142. {
  143. public:
  144. promise_moved():
  145. future_error(system::make_error_code(future_errc::no_state))
  146. {}
  147. };
  148. namespace future_state
  149. {
  150. enum state { uninitialized, waiting, ready, moved, deferred };
  151. }
  152. namespace detail
  153. {
  154. struct relocker
  155. {
  156. boost::unique_lock<boost::mutex>& lock_;
  157. bool unlocked_;
  158. relocker(boost::unique_lock<boost::mutex>& lk):
  159. lock_(lk)
  160. {
  161. lock_.unlock();
  162. unlocked_=true;
  163. }
  164. ~relocker()
  165. {
  166. if (unlocked_) {
  167. lock_.lock();
  168. }
  169. }
  170. void lock() {
  171. if (unlocked_) {
  172. lock_.lock();
  173. unlocked_=false;
  174. }
  175. }
  176. private:
  177. relocker& operator=(relocker const&);
  178. };
  179. struct shared_state_base : enable_shared_from_this<shared_state_base>
  180. {
  181. typedef std::list<boost::condition_variable_any*> waiter_list;
  182. // This type should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
  183. typedef shared_ptr<shared_state_base> continuation_ptr_type;
  184. boost::exception_ptr exception;
  185. bool done;
  186. bool is_deferred_;
  187. launch policy_;
  188. bool is_constructed;
  189. mutable boost::mutex mutex;
  190. boost::condition_variable waiters;
  191. waiter_list external_waiters;
  192. boost::function<void()> callback;
  193. // This declaration should be only included conditionally if interruptions are allowed, but is included to maintain the same layout.
  194. bool thread_was_interrupted;
  195. // This declaration should be only included conditionally, but is included to maintain the same layout.
  196. continuation_ptr_type continuation_ptr;
  197. // This declaration should be only included conditionally, but is included to maintain the same layout.
  198. virtual void launch_continuation(boost::unique_lock<boost::mutex>&)
  199. {
  200. }
  201. shared_state_base():
  202. done(false),
  203. is_deferred_(false),
  204. policy_(launch::none),
  205. is_constructed(false),
  206. thread_was_interrupted(false),
  207. continuation_ptr()
  208. {}
  209. virtual ~shared_state_base()
  210. {}
  211. void set_deferred()
  212. {
  213. is_deferred_ = true;
  214. policy_ = launch::deferred;
  215. }
  216. void set_async()
  217. {
  218. is_deferred_ = false;
  219. policy_ = launch::async;
  220. }
  221. waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
  222. {
  223. boost::unique_lock<boost::mutex> lock(mutex);
  224. do_callback(lock);
  225. return external_waiters.insert(external_waiters.end(),&cv);
  226. }
  227. void remove_external_waiter(waiter_list::iterator it)
  228. {
  229. boost::lock_guard<boost::mutex> lock(mutex);
  230. external_waiters.erase(it);
  231. }
  232. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  233. void do_continuation(boost::unique_lock<boost::mutex>& lock)
  234. {
  235. if (continuation_ptr) {
  236. continuation_ptr->launch_continuation(lock);
  237. if (! lock.owns_lock())
  238. lock.lock();
  239. continuation_ptr.reset();
  240. }
  241. }
  242. #else
  243. void do_continuation(boost::unique_lock<boost::mutex>&)
  244. {
  245. }
  246. #endif
  247. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  248. void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
  249. {
  250. continuation_ptr= continuation;
  251. if (done) {
  252. do_continuation(lock);
  253. }
  254. }
  255. #endif
  256. void mark_finished_internal(boost::unique_lock<boost::mutex>& lock)
  257. {
  258. done=true;
  259. waiters.notify_all();
  260. for(waiter_list::const_iterator it=external_waiters.begin(),
  261. end=external_waiters.end();it!=end;++it)
  262. {
  263. (*it)->notify_all();
  264. }
  265. do_continuation(lock);
  266. }
  267. void make_ready()
  268. {
  269. boost::unique_lock<boost::mutex> lock(mutex);
  270. mark_finished_internal(lock);
  271. }
  272. void do_callback(boost::unique_lock<boost::mutex>& lock)
  273. {
  274. if(callback && !done)
  275. {
  276. boost::function<void()> local_callback=callback;
  277. relocker relock(lock);
  278. local_callback();
  279. }
  280. }
  281. void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
  282. {
  283. do_callback(lk);
  284. //if (!done) // fixme why this doesn't work?
  285. {
  286. if (is_deferred_)
  287. {
  288. is_deferred_=false;
  289. execute(lk);
  290. //lk.unlock();
  291. }
  292. else
  293. {
  294. while(!done)
  295. {
  296. waiters.wait(lk);
  297. }
  298. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  299. if(rethrow && thread_was_interrupted)
  300. {
  301. throw boost::thread_interrupted();
  302. }
  303. #endif
  304. if(rethrow && exception)
  305. {
  306. boost::rethrow_exception(exception);
  307. }
  308. }
  309. }
  310. }
  311. virtual void wait(bool rethrow=true)
  312. {
  313. boost::unique_lock<boost::mutex> lock(mutex);
  314. wait_internal(lock, rethrow);
  315. }
  316. #if defined BOOST_THREAD_USES_DATETIME
  317. bool timed_wait_until(boost::system_time const& target_time)
  318. {
  319. boost::unique_lock<boost::mutex> lock(mutex);
  320. if (is_deferred_)
  321. return false;
  322. do_callback(lock);
  323. while(!done)
  324. {
  325. bool const success=waiters.timed_wait(lock,target_time);
  326. if(!success && !done)
  327. {
  328. return false;
  329. }
  330. }
  331. return true;
  332. }
  333. #endif
  334. #ifdef BOOST_THREAD_USES_CHRONO
  335. template <class Clock, class Duration>
  336. future_status
  337. wait_until(const chrono::time_point<Clock, Duration>& abs_time)
  338. {
  339. boost::unique_lock<boost::mutex> lock(mutex);
  340. if (is_deferred_)
  341. return future_status::deferred;
  342. do_callback(lock);
  343. while(!done)
  344. {
  345. cv_status const st=waiters.wait_until(lock,abs_time);
  346. if(st==cv_status::timeout && !done)
  347. {
  348. return future_status::timeout;
  349. }
  350. }
  351. return future_status::ready;
  352. }
  353. #endif
  354. void mark_exceptional_finish_internal(boost::exception_ptr const& e, boost::unique_lock<boost::mutex>& lock)
  355. {
  356. exception=e;
  357. mark_finished_internal(lock);
  358. }
  359. void mark_exceptional_finish()
  360. {
  361. boost::unique_lock<boost::mutex> lock(mutex);
  362. mark_exceptional_finish_internal(boost::current_exception(), lock);
  363. }
  364. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  365. void mark_interrupted_finish()
  366. {
  367. boost::unique_lock<boost::mutex> lock(mutex);
  368. thread_was_interrupted=true;
  369. mark_finished_internal(lock);
  370. }
  371. void set_interrupted_at_thread_exit()
  372. {
  373. unique_lock<boost::mutex> lk(mutex);
  374. thread_was_interrupted=true;
  375. if (has_value(lk))
  376. {
  377. throw_exception(promise_already_satisfied());
  378. }
  379. detail::make_ready_at_thread_exit(shared_from_this());
  380. }
  381. #endif
  382. void set_exception_at_thread_exit(exception_ptr e)
  383. {
  384. unique_lock<boost::mutex> lk(mutex);
  385. if (has_value(lk))
  386. {
  387. throw_exception(promise_already_satisfied());
  388. }
  389. exception=e;
  390. this->is_constructed = true;
  391. detail::make_ready_at_thread_exit(shared_from_this());
  392. }
  393. bool has_value() const
  394. {
  395. boost::lock_guard<boost::mutex> lock(mutex);
  396. return done && !(exception
  397. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  398. || thread_was_interrupted
  399. #endif
  400. );
  401. }
  402. bool has_value(unique_lock<boost::mutex>& ) const
  403. {
  404. return done && !(exception
  405. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  406. || thread_was_interrupted
  407. #endif
  408. );
  409. }
  410. bool has_exception() const
  411. {
  412. boost::lock_guard<boost::mutex> lock(mutex);
  413. return done && (exception
  414. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  415. || thread_was_interrupted
  416. #endif
  417. );
  418. }
  419. bool has_exception(unique_lock<boost::mutex>&) const
  420. {
  421. return done && (exception
  422. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  423. || thread_was_interrupted
  424. #endif
  425. );
  426. }
  427. bool is_deferred(boost::lock_guard<boost::mutex>&) const {
  428. return is_deferred_;
  429. }
  430. launch launch_policy(boost::unique_lock<boost::mutex>&) const
  431. {
  432. return policy_;
  433. }
  434. future_state::state get_state() const
  435. {
  436. boost::lock_guard<boost::mutex> guard(mutex);
  437. if(!done)
  438. {
  439. return future_state::waiting;
  440. }
  441. else
  442. {
  443. return future_state::ready;
  444. }
  445. }
  446. exception_ptr get_exception_ptr()
  447. {
  448. boost::unique_lock<boost::mutex> lock(mutex);
  449. return get_exception_ptr(lock);
  450. }
  451. exception_ptr get_exception_ptr(boost::unique_lock<boost::mutex>& lock)
  452. {
  453. wait_internal(lock, false);
  454. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  455. if(thread_was_interrupted)
  456. {
  457. return copy_exception(boost::thread_interrupted());
  458. }
  459. #endif
  460. return exception;
  461. }
  462. template<typename F,typename U>
  463. void set_wait_callback(F f,U* u)
  464. {
  465. boost::lock_guard<boost::mutex> lock(mutex);
  466. callback=boost::bind(f,boost::ref(*u));
  467. }
  468. virtual void execute(boost::unique_lock<boost::mutex>&) {}
  469. private:
  470. shared_state_base(shared_state_base const&);
  471. shared_state_base& operator=(shared_state_base const&);
  472. };
  473. template<typename T>
  474. struct future_traits
  475. {
  476. typedef boost::scoped_ptr<T> storage_type;
  477. struct dummy;
  478. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  479. typedef T const& source_reference_type;
  480. //typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
  481. typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
  482. //typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type;
  483. typedef T move_dest_type;
  484. #elif defined BOOST_THREAD_USES_MOVE
  485. typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,T&>::type source_reference_type;
  486. //typedef typename boost::mpl::if_c<boost::is_fundamental<T>::value,T,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
  487. //typedef typename boost::mpl::if_c<boost::enable_move_utility_emulation<T>::value,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
  488. typedef BOOST_THREAD_RV_REF(T) rvalue_source_type;
  489. typedef T move_dest_type;
  490. #else
  491. typedef T& source_reference_type;
  492. typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type;
  493. typedef typename boost::mpl::if_<boost::thread_detail::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;
  494. #endif
  495. typedef const T& shared_future_get_result_type;
  496. static void init(storage_type& storage,source_reference_type t)
  497. {
  498. storage.reset(new T(t));
  499. }
  500. static void init(storage_type& storage,rvalue_source_type t)
  501. {
  502. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  503. storage.reset(new T(boost::forward<T>(t)));
  504. #else
  505. storage.reset(new T(static_cast<rvalue_source_type>(t)));
  506. #endif
  507. }
  508. static void cleanup(storage_type& storage)
  509. {
  510. storage.reset();
  511. }
  512. };
  513. template<typename T>
  514. struct future_traits<T&>
  515. {
  516. typedef T* storage_type;
  517. typedef T& source_reference_type;
  518. //struct rvalue_source_type
  519. //{};
  520. typedef T& move_dest_type;
  521. typedef T& shared_future_get_result_type;
  522. static void init(storage_type& storage,T& t)
  523. {
  524. storage=&t;
  525. }
  526. static void cleanup(storage_type& storage)
  527. {
  528. storage=0;
  529. }
  530. };
  531. template<>
  532. struct future_traits<void>
  533. {
  534. typedef bool storage_type;
  535. typedef void move_dest_type;
  536. typedef void shared_future_get_result_type;
  537. static void init(storage_type& storage)
  538. {
  539. storage=true;
  540. }
  541. static void cleanup(storage_type& storage)
  542. {
  543. storage=false;
  544. }
  545. };
  546. // Used to create stand-alone futures
  547. template<typename T>
  548. struct shared_state:
  549. detail::shared_state_base
  550. {
  551. typedef typename future_traits<T>::storage_type storage_type;
  552. typedef typename future_traits<T>::source_reference_type source_reference_type;
  553. typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;
  554. typedef typename future_traits<T>::move_dest_type move_dest_type;
  555. typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type;
  556. storage_type result;
  557. shared_state():
  558. result(0)
  559. {}
  560. ~shared_state()
  561. {}
  562. void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
  563. {
  564. future_traits<T>::init(result,result_);
  565. this->mark_finished_internal(lock);
  566. }
  567. void mark_finished_with_result_internal(rvalue_source_type result_, boost::unique_lock<boost::mutex>& lock)
  568. {
  569. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  570. future_traits<T>::init(result,boost::forward<T>(result_));
  571. #else
  572. future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
  573. #endif
  574. this->mark_finished_internal(lock);
  575. }
  576. void mark_finished_with_result(source_reference_type result_)
  577. {
  578. boost::unique_lock<boost::mutex> lock(mutex);
  579. this->mark_finished_with_result_internal(result_, lock);
  580. }
  581. void mark_finished_with_result(rvalue_source_type result_)
  582. {
  583. boost::unique_lock<boost::mutex> lock(mutex);
  584. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  585. mark_finished_with_result_internal(boost::forward<T>(result_), lock);
  586. #else
  587. mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_), lock);
  588. #endif
  589. }
  590. virtual move_dest_type get()
  591. {
  592. wait();
  593. return boost::move(*result);
  594. }
  595. virtual shared_future_get_result_type get_sh()
  596. {
  597. wait();
  598. return *result;
  599. }
  600. //void set_value_at_thread_exit(const T & result_)
  601. void set_value_at_thread_exit(source_reference_type result_)
  602. {
  603. unique_lock<boost::mutex> lk(this->mutex);
  604. if (this->has_value(lk))
  605. {
  606. throw_exception(promise_already_satisfied());
  607. }
  608. //future_traits<T>::init(result,result_);
  609. result.reset(new T(result_));
  610. this->is_constructed = true;
  611. detail::make_ready_at_thread_exit(shared_from_this());
  612. }
  613. //void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T) result_)
  614. void set_value_at_thread_exit(rvalue_source_type result_)
  615. {
  616. unique_lock<boost::mutex> lk(this->mutex);
  617. if (this->has_value(lk))
  618. throw_exception(promise_already_satisfied());
  619. result.reset(new T(boost::move(result_)));
  620. //future_traits<T>::init(result,static_cast<rvalue_source_type>(result_));
  621. this->is_constructed = true;
  622. detail::make_ready_at_thread_exit(shared_from_this());
  623. }
  624. private:
  625. shared_state(shared_state const&);
  626. shared_state& operator=(shared_state const&);
  627. };
  628. template<typename T>
  629. struct shared_state<T&>:
  630. detail::shared_state_base
  631. {
  632. typedef typename future_traits<T&>::storage_type storage_type;
  633. typedef typename future_traits<T&>::source_reference_type source_reference_type;
  634. typedef typename future_traits<T&>::move_dest_type move_dest_type;
  635. typedef typename future_traits<T&>::shared_future_get_result_type shared_future_get_result_type;
  636. T* result;
  637. shared_state():
  638. result(0)
  639. {}
  640. ~shared_state()
  641. {
  642. }
  643. void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
  644. {
  645. //future_traits<T>::init(result,result_);
  646. result= &result_;
  647. mark_finished_internal(lock);
  648. }
  649. void mark_finished_with_result(source_reference_type result_)
  650. {
  651. boost::unique_lock<boost::mutex> lock(mutex);
  652. mark_finished_with_result_internal(result_, lock);
  653. }
  654. virtual T& get()
  655. {
  656. wait();
  657. return *result;
  658. }
  659. virtual T& get_sh()
  660. {
  661. wait();
  662. return *result;
  663. }
  664. void set_value_at_thread_exit(T& result_)
  665. {
  666. unique_lock<boost::mutex> lk(this->mutex);
  667. if (this->has_value(lk))
  668. throw_exception(promise_already_satisfied());
  669. //future_traits<T>::init(result,result_);
  670. result= &result_;
  671. this->is_constructed = true;
  672. detail::make_ready_at_thread_exit(shared_from_this());
  673. }
  674. private:
  675. shared_state(shared_state const&);
  676. shared_state& operator=(shared_state const&);
  677. };
  678. template<>
  679. struct shared_state<void>:
  680. detail::shared_state_base
  681. {
  682. typedef void shared_future_get_result_type;
  683. shared_state()
  684. {}
  685. void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
  686. {
  687. mark_finished_internal(lock);
  688. }
  689. void mark_finished_with_result()
  690. {
  691. boost::unique_lock<boost::mutex> lock(mutex);
  692. mark_finished_with_result_internal(lock);
  693. }
  694. virtual void get()
  695. {
  696. this->wait();
  697. }
  698. virtual void get_sh()
  699. {
  700. wait();
  701. }
  702. void set_value_at_thread_exit()
  703. {
  704. unique_lock<boost::mutex> lk(this->mutex);
  705. if (this->has_value(lk))
  706. {
  707. throw_exception(promise_already_satisfied());
  708. }
  709. this->is_constructed = true;
  710. detail::make_ready_at_thread_exit(shared_from_this());
  711. }
  712. private:
  713. shared_state(shared_state const&);
  714. shared_state& operator=(shared_state const&);
  715. };
  716. /////////////////////////
  717. /// future_async_shared_state_base
  718. /////////////////////////
  719. template<typename Rp>
  720. struct future_async_shared_state_base: shared_state<Rp>
  721. {
  722. typedef shared_state<Rp> base_type;
  723. protected:
  724. boost::thread thr_;
  725. void join()
  726. {
  727. if (thr_.joinable()) thr_.join();
  728. }
  729. public:
  730. future_async_shared_state_base()
  731. {
  732. this->set_async();
  733. }
  734. explicit future_async_shared_state_base(BOOST_THREAD_RV_REF(boost::thread) th) :
  735. thr_(boost::move(th))
  736. {
  737. this->set_async();
  738. }
  739. ~future_async_shared_state_base()
  740. {
  741. join();
  742. }
  743. virtual void wait(bool rethrow)
  744. {
  745. join();
  746. this->base_type::wait(rethrow);
  747. }
  748. };
  749. /////////////////////////
  750. /// future_async_shared_state
  751. /////////////////////////
  752. template<typename Rp, typename Fp>
  753. struct future_async_shared_state: future_async_shared_state_base<Rp>
  754. {
  755. typedef future_async_shared_state_base<Rp> base_type;
  756. public:
  757. explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
  758. base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
  759. {
  760. }
  761. static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
  762. {
  763. try
  764. {
  765. that->mark_finished_with_result(f());
  766. }
  767. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  768. catch(thread_interrupted& )
  769. {
  770. that->mark_interrupted_finish();
  771. }
  772. #endif
  773. catch(...)
  774. {
  775. that->mark_exceptional_finish();
  776. }
  777. }
  778. };
  779. template<typename Fp>
  780. struct future_async_shared_state<void, Fp>: public future_async_shared_state_base<void>
  781. {
  782. typedef future_async_shared_state_base<void> base_type;
  783. public:
  784. explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
  785. base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
  786. {
  787. }
  788. static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
  789. {
  790. try
  791. {
  792. f();
  793. that->mark_finished_with_result();
  794. }
  795. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  796. catch(thread_interrupted& )
  797. {
  798. that->mark_interrupted_finish();
  799. }
  800. #endif
  801. catch(...)
  802. {
  803. that->mark_exceptional_finish();
  804. }
  805. }
  806. };
  807. template<typename Rp, typename Fp>
  808. struct future_async_shared_state<Rp&, Fp>: future_async_shared_state_base<Rp&>
  809. {
  810. typedef future_async_shared_state_base<Rp&> base_type;
  811. public:
  812. explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) :
  813. base_type(thread(&future_async_shared_state::run, this, boost::forward<Fp>(f)))
  814. {
  815. }
  816. static void run(future_async_shared_state* that, BOOST_THREAD_FWD_REF(Fp) f)
  817. {
  818. try
  819. {
  820. that->mark_finished_with_result(f());
  821. }
  822. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  823. catch(thread_interrupted& )
  824. {
  825. that->mark_interrupted_finish();
  826. }
  827. #endif
  828. catch(...)
  829. {
  830. that->mark_exceptional_finish();
  831. }
  832. }
  833. };
  834. //////////////////////////
  835. /// future_deferred_shared_state
  836. //////////////////////////
  837. template<typename Rp, typename Fp>
  838. struct future_deferred_shared_state: shared_state<Rp>
  839. {
  840. typedef shared_state<Rp> base_type;
  841. Fp func_;
  842. public:
  843. explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
  844. : func_(boost::forward<Fp>(f))
  845. {
  846. this->set_deferred();
  847. }
  848. virtual void execute(boost::unique_lock<boost::mutex>& lck) {
  849. try
  850. {
  851. Fp local_fuct=boost::move(func_);
  852. relocker relock(lck);
  853. Rp res = local_fuct();
  854. relock.lock();
  855. this->mark_finished_with_result_internal(boost::move(res), lck);
  856. }
  857. catch (...)
  858. {
  859. this->mark_exceptional_finish_internal(current_exception(), lck);
  860. }
  861. }
  862. };
  863. template<typename Rp, typename Fp>
  864. struct future_deferred_shared_state<Rp&,Fp>: shared_state<Rp&>
  865. {
  866. typedef shared_state<Rp&> base_type;
  867. Fp func_;
  868. public:
  869. explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
  870. : func_(boost::forward<Fp>(f))
  871. {
  872. this->set_deferred();
  873. }
  874. virtual void execute(boost::unique_lock<boost::mutex>& lck) {
  875. try
  876. {
  877. this->mark_finished_with_result_internal(func_(), lck);
  878. }
  879. catch (...)
  880. {
  881. this->mark_exceptional_finish_internal(current_exception(), lck);
  882. }
  883. }
  884. };
  885. template<typename Fp>
  886. struct future_deferred_shared_state<void,Fp>: shared_state<void>
  887. {
  888. typedef shared_state<void> base_type;
  889. Fp func_;
  890. public:
  891. explicit future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
  892. : func_(boost::forward<Fp>(f))
  893. {
  894. this->set_deferred();
  895. }
  896. virtual void execute(boost::unique_lock<boost::mutex>& lck) {
  897. try
  898. {
  899. Fp local_fuct=boost::move(func_);
  900. relocker relock(lck);
  901. local_fuct();
  902. relock.lock();
  903. this->mark_finished_with_result_internal(lck);
  904. }
  905. catch (...)
  906. {
  907. this->mark_exceptional_finish_internal(current_exception(), lck);
  908. }
  909. }
  910. };
  911. // template<typename T, typename Allocator>
  912. // struct shared_state_alloc: public shared_state<T>
  913. // {
  914. // typedef shared_state<T> base;
  915. // Allocator alloc_;
  916. //
  917. // public:
  918. // explicit shared_state_alloc(const Allocator& a)
  919. // : alloc_(a) {}
  920. //
  921. // };
  922. class future_waiter
  923. {
  924. struct registered_waiter;
  925. typedef std::vector<int>::size_type count_type;
  926. struct registered_waiter
  927. {
  928. boost::shared_ptr<detail::shared_state_base> future_;
  929. detail::shared_state_base::waiter_list::iterator wait_iterator;
  930. count_type index;
  931. registered_waiter(boost::shared_ptr<detail::shared_state_base> const& a_future,
  932. detail::shared_state_base::waiter_list::iterator wait_iterator_,
  933. count_type index_):
  934. future_(a_future),wait_iterator(wait_iterator_),index(index_)
  935. {}
  936. };
  937. struct all_futures_lock
  938. {
  939. #ifdef _MANAGED
  940. typedef std::ptrdiff_t count_type_portable;
  941. #else
  942. typedef count_type count_type_portable;
  943. #endif
  944. count_type_portable count;
  945. boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
  946. all_futures_lock(std::vector<registered_waiter>& futures):
  947. count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
  948. {
  949. for(count_type_portable i=0;i<count;++i)
  950. {
  951. #if defined __DECCXX || defined __SUNPRO_CC || defined __hpux
  952. locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move();
  953. #else
  954. locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex);
  955. #endif
  956. }
  957. }
  958. void lock()
  959. {
  960. boost::lock(locks.get(),locks.get()+count);
  961. }
  962. void unlock()
  963. {
  964. for(count_type_portable i=0;i<count;++i)
  965. {
  966. locks[i].unlock();
  967. }
  968. }
  969. };
  970. boost::condition_variable_any cv;
  971. std::vector<registered_waiter> futures;
  972. count_type future_count;
  973. public:
  974. future_waiter():
  975. future_count(0)
  976. {}
  977. template<typename F>
  978. void add(F& f)
  979. {
  980. if(f.future_)
  981. {
  982. futures.push_back(registered_waiter(f.future_,f.future_->register_external_waiter(cv),future_count));
  983. }
  984. ++future_count;
  985. }
  986. count_type wait()
  987. {
  988. all_futures_lock lk(futures);
  989. for(;;)
  990. {
  991. for(count_type i=0;i<futures.size();++i)
  992. {
  993. if(futures[i].future_->done)
  994. {
  995. return futures[i].index;
  996. }
  997. }
  998. cv.wait(lk);
  999. }
  1000. }
  1001. ~future_waiter()
  1002. {
  1003. for(count_type i=0;i<futures.size();++i)
  1004. {
  1005. futures[i].future_->remove_external_waiter(futures[i].wait_iterator);
  1006. }
  1007. }
  1008. };
  1009. }
  1010. template <typename R>
  1011. class BOOST_THREAD_FUTURE;
  1012. template <typename R>
  1013. class shared_future;
  1014. template<typename T>
  1015. struct is_future_type
  1016. {
  1017. BOOST_STATIC_CONSTANT(bool, value=false);
  1018. typedef void type;
  1019. };
  1020. template<typename T>
  1021. struct is_future_type<BOOST_THREAD_FUTURE<T> >
  1022. {
  1023. BOOST_STATIC_CONSTANT(bool, value=true);
  1024. typedef T type;
  1025. };
  1026. template<typename T>
  1027. struct is_future_type<shared_future<T> >
  1028. {
  1029. BOOST_STATIC_CONSTANT(bool, value=true);
  1030. typedef T type;
  1031. };
  1032. template<typename Iterator>
  1033. typename boost::disable_if<is_future_type<Iterator>,void>::type wait_for_all(Iterator begin,Iterator end)
  1034. {
  1035. for(Iterator current=begin;current!=end;++current)
  1036. {
  1037. current->wait();
  1038. }
  1039. }
  1040. template<typename F1,typename F2>
  1041. typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1,F2& f2)
  1042. {
  1043. f1.wait();
  1044. f2.wait();
  1045. }
  1046. template<typename F1,typename F2,typename F3>
  1047. void wait_for_all(F1& f1,F2& f2,F3& f3)
  1048. {
  1049. f1.wait();
  1050. f2.wait();
  1051. f3.wait();
  1052. }
  1053. template<typename F1,typename F2,typename F3,typename F4>
  1054. void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)
  1055. {
  1056. f1.wait();
  1057. f2.wait();
  1058. f3.wait();
  1059. f4.wait();
  1060. }
  1061. template<typename F1,typename F2,typename F3,typename F4,typename F5>
  1062. void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
  1063. {
  1064. f1.wait();
  1065. f2.wait();
  1066. f3.wait();
  1067. f4.wait();
  1068. f5.wait();
  1069. }
  1070. template<typename Iterator>
  1071. typename boost::disable_if<is_future_type<Iterator>,Iterator>::type wait_for_any(Iterator begin,Iterator end)
  1072. {
  1073. if(begin==end)
  1074. return end;
  1075. detail::future_waiter waiter;
  1076. for(Iterator current=begin;current!=end;++current)
  1077. {
  1078. waiter.add(*current);
  1079. }
  1080. return boost::next(begin,waiter.wait());
  1081. }
  1082. template<typename F1,typename F2>
  1083. typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2)
  1084. {
  1085. detail::future_waiter waiter;
  1086. waiter.add(f1);
  1087. waiter.add(f2);
  1088. return waiter.wait();
  1089. }
  1090. template<typename F1,typename F2,typename F3>
  1091. unsigned wait_for_any(F1& f1,F2& f2,F3& f3)
  1092. {
  1093. detail::future_waiter waiter;
  1094. waiter.add(f1);
  1095. waiter.add(f2);
  1096. waiter.add(f3);
  1097. return waiter.wait();
  1098. }
  1099. template<typename F1,typename F2,typename F3,typename F4>
  1100. unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
  1101. {
  1102. detail::future_waiter waiter;
  1103. waiter.add(f1);
  1104. waiter.add(f2);
  1105. waiter.add(f3);
  1106. waiter.add(f4);
  1107. return waiter.wait();
  1108. }
  1109. template<typename F1,typename F2,typename F3,typename F4,typename F5>
  1110. unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
  1111. {
  1112. detail::future_waiter waiter;
  1113. waiter.add(f1);
  1114. waiter.add(f2);
  1115. waiter.add(f3);
  1116. waiter.add(f4);
  1117. waiter.add(f5);
  1118. return waiter.wait();
  1119. }
  1120. template <typename R>
  1121. class promise;
  1122. template <typename R>
  1123. class packaged_task;
  1124. namespace detail
  1125. {
  1126. /// Common implementation for all the futures independently of the return type
  1127. class base_future
  1128. {
  1129. //BOOST_THREAD_MOVABLE(base_future)
  1130. };
  1131. /// Common implementation for future and shared_future.
  1132. template <typename R>
  1133. class basic_future : public base_future
  1134. {
  1135. protected:
  1136. public:
  1137. typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
  1138. future_ptr future_;
  1139. basic_future(future_ptr a_future):
  1140. future_(a_future)
  1141. {
  1142. }
  1143. // Copy construction from a shared_future
  1144. explicit basic_future(const shared_future<R>&) BOOST_NOEXCEPT;
  1145. public:
  1146. typedef future_state::state state;
  1147. BOOST_THREAD_MOVABLE(basic_future)
  1148. basic_future(): future_() {}
  1149. ~basic_future() {}
  1150. basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
  1151. future_(BOOST_THREAD_RV(other).future_)
  1152. {
  1153. BOOST_THREAD_RV(other).future_.reset();
  1154. }
  1155. basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
  1156. {
  1157. future_=BOOST_THREAD_RV(other).future_;
  1158. BOOST_THREAD_RV(other).future_.reset();
  1159. return *this;
  1160. }
  1161. void swap(basic_future& that) BOOST_NOEXCEPT
  1162. {
  1163. future_.swap(that.future_);
  1164. }
  1165. // functions to check state, and wait for ready
  1166. state get_state() const
  1167. {
  1168. if(!future_)
  1169. {
  1170. return future_state::uninitialized;
  1171. }
  1172. return future_->get_state();
  1173. }
  1174. bool is_ready() const
  1175. {
  1176. return get_state()==future_state::ready;
  1177. }
  1178. bool has_exception() const
  1179. {
  1180. return future_ && future_->has_exception();
  1181. }
  1182. bool has_value() const
  1183. {
  1184. return future_ && future_->has_value();
  1185. }
  1186. launch launch_policy(boost::unique_lock<boost::mutex>& lk) const
  1187. {
  1188. if ( future_ ) return future_->launch_policy(lk);
  1189. else return launch(launch::none);
  1190. }
  1191. exception_ptr get_exception_ptr()
  1192. {
  1193. return future_
  1194. ? future_->get_exception_ptr()
  1195. : exception_ptr();
  1196. }
  1197. bool valid() const BOOST_NOEXCEPT
  1198. {
  1199. return future_ != 0;
  1200. }
  1201. void wait() const
  1202. {
  1203. if(!future_)
  1204. {
  1205. boost::throw_exception(future_uninitialized());
  1206. }
  1207. future_->wait(false);
  1208. }
  1209. #if defined BOOST_THREAD_USES_DATETIME
  1210. template<typename Duration>
  1211. bool timed_wait(Duration const& rel_time) const
  1212. {
  1213. return timed_wait_until(boost::get_system_time()+rel_time);
  1214. }
  1215. bool timed_wait_until(boost::system_time const& abs_time) const
  1216. {
  1217. if(!future_)
  1218. {
  1219. boost::throw_exception(future_uninitialized());
  1220. }
  1221. return future_->timed_wait_until(abs_time);
  1222. }
  1223. #endif
  1224. #ifdef BOOST_THREAD_USES_CHRONO
  1225. template <class Rep, class Period>
  1226. future_status
  1227. wait_for(const chrono::duration<Rep, Period>& rel_time) const
  1228. {
  1229. return wait_until(chrono::steady_clock::now() + rel_time);
  1230. }
  1231. template <class Clock, class Duration>
  1232. future_status
  1233. wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
  1234. {
  1235. if(!future_)
  1236. {
  1237. boost::throw_exception(future_uninitialized());
  1238. }
  1239. return future_->wait_until(abs_time);
  1240. }
  1241. #endif
  1242. };
  1243. } // detail
  1244. BOOST_THREAD_DCL_MOVABLE_BEG(R) detail::basic_future<R> BOOST_THREAD_DCL_MOVABLE_END
  1245. namespace detail
  1246. {
  1247. #if (!defined _MSC_VER || _MSC_VER >= 1400) // _MSC_VER == 1400 on MSVC 2005
  1248. template <class Rp, class Fp>
  1249. BOOST_THREAD_FUTURE<Rp>
  1250. make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
  1251. template <class Rp, class Fp>
  1252. BOOST_THREAD_FUTURE<Rp>
  1253. make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
  1254. #endif // #if (!defined _MSC_VER || _MSC_VER >= 1400)
  1255. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1256. template<typename F, typename Rp, typename Fp>
  1257. struct future_deferred_continuation_shared_state;
  1258. template<typename F, typename Rp, typename Fp>
  1259. struct future_async_continuation_shared_state;
  1260. template <class F, class Rp, class Fp>
  1261. BOOST_THREAD_FUTURE<Rp>
  1262. make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1263. template <class F, class Rp, class Fp>
  1264. BOOST_THREAD_FUTURE<Rp>
  1265. make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1266. #endif
  1267. #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  1268. template<typename F, typename Rp>
  1269. struct future_unwrap_shared_state;
  1270. template <class F, class Rp>
  1271. inline BOOST_THREAD_FUTURE<Rp>
  1272. make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
  1273. #endif
  1274. }
  1275. template <typename R>
  1276. class BOOST_THREAD_FUTURE : public detail::basic_future<R>
  1277. {
  1278. private:
  1279. typedef detail::basic_future<R> base_type;
  1280. typedef typename base_type::future_ptr future_ptr;
  1281. friend class shared_future<R>;
  1282. friend class promise<R>;
  1283. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1284. template <typename, typename, typename>
  1285. friend struct detail::future_async_continuation_shared_state;
  1286. template <typename, typename, typename>
  1287. friend struct detail::future_deferred_continuation_shared_state;
  1288. template <class F, class Rp, class Fp>
  1289. friend BOOST_THREAD_FUTURE<Rp>
  1290. detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1291. template <class F, class Rp, class Fp>
  1292. friend BOOST_THREAD_FUTURE<Rp>
  1293. detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1294. #endif
  1295. #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  1296. template<typename F, typename Rp>
  1297. friend struct detail::future_unwrap_shared_state;
  1298. template <class F, class Rp>
  1299. friend BOOST_THREAD_FUTURE<Rp>
  1300. detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
  1301. #endif
  1302. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  1303. template <class> friend class packaged_task; // todo check if this works in windows
  1304. #else
  1305. friend class packaged_task<R>;
  1306. #endif
  1307. friend class detail::future_waiter;
  1308. template <class Rp, class Fp>
  1309. friend BOOST_THREAD_FUTURE<Rp>
  1310. detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
  1311. template <class Rp, class Fp>
  1312. friend BOOST_THREAD_FUTURE<Rp>
  1313. detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
  1314. typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
  1315. BOOST_THREAD_FUTURE(future_ptr a_future):
  1316. base_type(a_future)
  1317. {
  1318. }
  1319. public:
  1320. BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
  1321. typedef future_state::state state;
  1322. typedef R value_type; // EXTENSION
  1323. BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
  1324. ~BOOST_THREAD_FUTURE() {}
  1325. BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
  1326. base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
  1327. {
  1328. }
  1329. inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
  1330. BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
  1331. {
  1332. this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
  1333. return *this;
  1334. }
  1335. shared_future<R> share()
  1336. {
  1337. return shared_future<R>(::boost::move(*this));
  1338. }
  1339. void swap(BOOST_THREAD_FUTURE& other)
  1340. {
  1341. static_cast<base_type*>(this)->swap(other);
  1342. }
  1343. // todo this function must be private and friendship provided to the internal users.
  1344. void set_async()
  1345. {
  1346. this->future_->set_async();
  1347. }
  1348. // todo this function must be private and friendship provided to the internal users.
  1349. void set_deferred()
  1350. {
  1351. this->future_->set_deferred();
  1352. }
  1353. // retrieving the value
  1354. move_dest_type get()
  1355. {
  1356. if(!this->future_)
  1357. {
  1358. boost::throw_exception(future_uninitialized());
  1359. }
  1360. future_ptr fut_=this->future_;
  1361. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  1362. this->future_.reset();
  1363. #endif
  1364. return fut_->get();
  1365. }
  1366. template <typename R2>
  1367. typename boost::disable_if< is_void<R2>, move_dest_type>::type
  1368. get_or(BOOST_THREAD_RV_REF(R2) v)
  1369. {
  1370. if(!this->future_)
  1371. {
  1372. boost::throw_exception(future_uninitialized());
  1373. }
  1374. this->future_->wait(false);
  1375. future_ptr fut_=this->future_;
  1376. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  1377. this->future_.reset();
  1378. #endif
  1379. if (fut_->has_value()) {
  1380. return fut_->get();
  1381. }
  1382. else {
  1383. return boost::move(v);
  1384. }
  1385. }
  1386. template <typename R2>
  1387. typename boost::disable_if< is_void<R2>, move_dest_type>::type
  1388. get_or(R2 const& v) // EXTENSION
  1389. {
  1390. if(!this->future_)
  1391. {
  1392. boost::throw_exception(future_uninitialized());
  1393. }
  1394. this->future_->wait(false);
  1395. future_ptr fut_=this->future_;
  1396. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  1397. this->future_.reset();
  1398. #endif
  1399. if (fut_->has_value()) {
  1400. return fut_->get();
  1401. }
  1402. else {
  1403. return v;
  1404. }
  1405. }
  1406. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1407. // template<typename F>
  1408. // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
  1409. //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  1410. // template<typename RF>
  1411. // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
  1412. // template<typename RF>
  1413. // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
  1414. //#endif
  1415. template<typename F>
  1416. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
  1417. then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
  1418. template<typename F>
  1419. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
  1420. then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
  1421. template <typename R2>
  1422. inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
  1423. fallback_to(BOOST_THREAD_RV_REF(R2) v); // EXTENSION
  1424. template <typename R2>
  1425. inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
  1426. fallback_to(R2 const& v); // EXTENSION
  1427. #endif
  1428. //#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  1429. // inline
  1430. // typename boost::enable_if<
  1431. // is_future_type<value_type>,
  1432. // value_type
  1433. // //BOOST_THREAD_FUTURE<typename is_future_type<value_type>::type>
  1434. // >::type
  1435. // unwrap();
  1436. //#endif
  1437. };
  1438. BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END
  1439. template <typename R2>
  1440. class BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> > : public detail::basic_future<BOOST_THREAD_FUTURE<R2> >
  1441. {
  1442. typedef BOOST_THREAD_FUTURE<R2> R;
  1443. private:
  1444. typedef detail::basic_future<R> base_type;
  1445. typedef typename base_type::future_ptr future_ptr;
  1446. friend class shared_future<R>;
  1447. friend class promise<R>;
  1448. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1449. template <typename, typename, typename>
  1450. friend struct detail::future_async_continuation_shared_state;
  1451. template <typename, typename, typename>
  1452. friend struct detail::future_deferred_continuation_shared_state;
  1453. template <class F, class Rp, class Fp>
  1454. friend BOOST_THREAD_FUTURE<Rp>
  1455. detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1456. template <class F, class Rp, class Fp>
  1457. friend BOOST_THREAD_FUTURE<Rp>
  1458. detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1459. #endif
  1460. #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  1461. template<typename F, typename Rp>
  1462. friend struct detail::future_unwrap_shared_state;
  1463. template <class F, class Rp>
  1464. friend BOOST_THREAD_FUTURE<Rp>
  1465. detail::make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f);
  1466. #endif
  1467. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  1468. template <class> friend class packaged_task; // todo check if this works in windows
  1469. #else
  1470. friend class packaged_task<R>;
  1471. #endif
  1472. friend class detail::future_waiter;
  1473. template <class Rp, class Fp>
  1474. friend BOOST_THREAD_FUTURE<Rp>
  1475. detail::make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
  1476. template <class Rp, class Fp>
  1477. friend BOOST_THREAD_FUTURE<Rp>
  1478. detail::make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f);
  1479. typedef typename detail::future_traits<R>::move_dest_type move_dest_type;
  1480. BOOST_THREAD_FUTURE(future_ptr a_future):
  1481. base_type(a_future)
  1482. {
  1483. }
  1484. public:
  1485. BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)
  1486. typedef future_state::state state;
  1487. typedef R value_type; // EXTENSION
  1488. BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
  1489. ~BOOST_THREAD_FUTURE() {}
  1490. BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
  1491. base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
  1492. {
  1493. }
  1494. BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT
  1495. {
  1496. this->base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
  1497. return *this;
  1498. }
  1499. shared_future<R> share()
  1500. {
  1501. return shared_future<R>(::boost::move(*this));
  1502. }
  1503. void swap(BOOST_THREAD_FUTURE& other)
  1504. {
  1505. static_cast<base_type*>(this)->swap(other);
  1506. }
  1507. // todo this function must be private and friendship provided to the internal users.
  1508. void set_async()
  1509. {
  1510. this->future_->set_async();
  1511. }
  1512. // todo this function must be private and friendship provided to the internal users.
  1513. void set_deferred()
  1514. {
  1515. this->future_->set_deferred();
  1516. }
  1517. // retrieving the value
  1518. move_dest_type get()
  1519. {
  1520. if(!this->future_)
  1521. {
  1522. boost::throw_exception(future_uninitialized());
  1523. }
  1524. future_ptr fut_=this->future_;
  1525. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  1526. this->future_.reset();
  1527. #endif
  1528. return fut_->get();
  1529. }
  1530. move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
  1531. {
  1532. if(!this->future_)
  1533. {
  1534. boost::throw_exception(future_uninitialized());
  1535. }
  1536. this->future_->wait(false);
  1537. future_ptr fut_=this->future_;
  1538. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  1539. this->future_.reset();
  1540. #endif
  1541. if (fut_->has_value()) return fut_->get();
  1542. else return boost::move(v);
  1543. }
  1544. move_dest_type get_or(R const& v) // EXTENSION
  1545. {
  1546. if(!this->future_)
  1547. {
  1548. boost::throw_exception(future_uninitialized());
  1549. }
  1550. this->future_->wait(false);
  1551. future_ptr fut_=this->future_;
  1552. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  1553. this->future_.reset();
  1554. #endif
  1555. if (fut_->has_value()) return fut_->get();
  1556. else return v;
  1557. }
  1558. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1559. // template<typename F>
  1560. // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
  1561. //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  1562. // template<typename RF>
  1563. // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
  1564. // template<typename RF>
  1565. // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
  1566. //#endif
  1567. template<typename F>
  1568. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
  1569. then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
  1570. template<typename F>
  1571. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE)>::type>
  1572. then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
  1573. #endif
  1574. #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  1575. inline
  1576. BOOST_THREAD_FUTURE<R2>
  1577. unwrap(); // EXTENSION
  1578. #endif
  1579. };
  1580. template <typename R>
  1581. class shared_future : public detail::basic_future<R>
  1582. {
  1583. typedef detail::basic_future<R> base_type;
  1584. typedef typename base_type::future_ptr future_ptr;
  1585. friend class detail::future_waiter;
  1586. friend class promise<R>;
  1587. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1588. template <typename, typename, typename>
  1589. friend struct detail::future_async_continuation_shared_state;
  1590. template <typename, typename, typename>
  1591. friend struct detail::future_deferred_continuation_shared_state;
  1592. template <class F, class Rp, class Fp>
  1593. friend BOOST_THREAD_FUTURE<Rp>
  1594. detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1595. template <class F, class Rp, class Fp>
  1596. friend BOOST_THREAD_FUTURE<Rp>
  1597. detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
  1598. #endif
  1599. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  1600. template <class> friend class packaged_task;// todo check if this works in windows
  1601. #else
  1602. friend class packaged_task<R>;
  1603. #endif
  1604. shared_future(future_ptr a_future):
  1605. base_type(a_future)
  1606. {}
  1607. public:
  1608. BOOST_THREAD_MOVABLE(shared_future)
  1609. typedef R value_type; // EXTENSION
  1610. shared_future(shared_future const& other):
  1611. base_type(other)
  1612. {}
  1613. typedef future_state::state state;
  1614. BOOST_CONSTEXPR shared_future()
  1615. {}
  1616. ~shared_future()
  1617. {}
  1618. shared_future& operator=(shared_future const& other)
  1619. {
  1620. shared_future(other).swap(*this);
  1621. return *this;
  1622. }
  1623. shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT :
  1624. base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
  1625. {
  1626. BOOST_THREAD_RV(other).future_.reset();
  1627. }
  1628. shared_future(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT :
  1629. base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
  1630. {
  1631. }
  1632. shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT
  1633. {
  1634. base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
  1635. return *this;
  1636. }
  1637. shared_future& operator=(BOOST_THREAD_RV_REF( BOOST_THREAD_FUTURE<R> ) other) BOOST_NOEXCEPT
  1638. {
  1639. base_type::operator=(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))));
  1640. return *this;
  1641. }
  1642. void swap(shared_future& other) BOOST_NOEXCEPT
  1643. {
  1644. static_cast<base_type*>(this)->swap(other);
  1645. }
  1646. // retrieving the value
  1647. typename detail::shared_state<R>::shared_future_get_result_type get()
  1648. {
  1649. if(!this->future_)
  1650. {
  1651. boost::throw_exception(future_uninitialized());
  1652. }
  1653. return this->future_->get_sh();
  1654. }
  1655. template <typename R2>
  1656. typename boost::disable_if< is_void<R2>, typename detail::shared_state<R>::shared_future_get_result_type>::type
  1657. get_or(BOOST_THREAD_RV_REF(R2) v) // EXTENSION
  1658. {
  1659. if(!this->future_)
  1660. {
  1661. boost::throw_exception(future_uninitialized());
  1662. }
  1663. future_ptr fut_=this->future_;
  1664. fut_->wait();
  1665. if (fut_->has_value()) return fut_->get_sh();
  1666. else return boost::move(v);
  1667. }
  1668. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  1669. // template<typename F>
  1670. // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
  1671. // template<typename F>
  1672. // auto then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
  1673. //#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  1674. // template<typename RF>
  1675. // inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(shared_future&));
  1676. // template<typename RF>
  1677. // inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(shared_future&));
  1678. //#endif
  1679. template<typename F>
  1680. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
  1681. then(BOOST_THREAD_FWD_REF(F) func); // EXTENSION
  1682. template<typename F>
  1683. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future)>::type>
  1684. then(launch policy, BOOST_THREAD_FWD_REF(F) func); // EXTENSION
  1685. #endif
  1686. //#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  1687. // inline
  1688. // typename boost::enable_if_c<
  1689. // is_future_type<value_type>::value,
  1690. // BOOST_THREAD_FUTURE<typename is_future_type<value_type>::type>
  1691. // >::type
  1692. // unwrap();
  1693. //#endif
  1694. };
  1695. BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END
  1696. namespace detail
  1697. {
  1698. /// Copy construction from a shared_future
  1699. template <typename R>
  1700. inline basic_future<R>::basic_future(const shared_future<R>& other) BOOST_NOEXCEPT
  1701. : future_(other.future_)
  1702. {
  1703. }
  1704. }
  1705. template <typename R>
  1706. class promise
  1707. {
  1708. typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
  1709. future_ptr future_;
  1710. bool future_obtained;
  1711. void lazy_init()
  1712. {
  1713. #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
  1714. #include <boost/detail/atomic_undef_macros.hpp>
  1715. if(!atomic_load(&future_))
  1716. {
  1717. future_ptr blank;
  1718. atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
  1719. }
  1720. #include <boost/detail/atomic_redef_macros.hpp>
  1721. #endif
  1722. }
  1723. public:
  1724. BOOST_THREAD_MOVABLE_ONLY(promise)
  1725. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  1726. template <class Allocator>
  1727. promise(boost::allocator_arg_t, Allocator a)
  1728. {
  1729. typedef typename Allocator::template rebind<detail::shared_state<R> >::other A2;
  1730. A2 a2(a);
  1731. typedef thread_detail::allocator_destructor<A2> D;
  1732. future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R>(), D(a2, 1) );
  1733. future_obtained = false;
  1734. }
  1735. #endif
  1736. promise():
  1737. #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
  1738. future_(),
  1739. #else
  1740. future_(new detail::shared_state<R>()),
  1741. #endif
  1742. future_obtained(false)
  1743. {}
  1744. ~promise()
  1745. {
  1746. if(future_)
  1747. {
  1748. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1749. if(!future_->done && !future_->is_constructed)
  1750. {
  1751. future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
  1752. }
  1753. }
  1754. }
  1755. // Assignment
  1756. promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
  1757. future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
  1758. {
  1759. BOOST_THREAD_RV(rhs).future_.reset();
  1760. BOOST_THREAD_RV(rhs).future_obtained=false;
  1761. }
  1762. promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
  1763. {
  1764. future_=BOOST_THREAD_RV(rhs).future_;
  1765. future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
  1766. BOOST_THREAD_RV(rhs).future_.reset();
  1767. BOOST_THREAD_RV(rhs).future_obtained=false;
  1768. return *this;
  1769. }
  1770. void swap(promise& other)
  1771. {
  1772. future_.swap(other.future_);
  1773. std::swap(future_obtained,other.future_obtained);
  1774. }
  1775. // Result retrieval
  1776. BOOST_THREAD_FUTURE<R> get_future()
  1777. {
  1778. lazy_init();
  1779. if (future_.get()==0)
  1780. {
  1781. boost::throw_exception(promise_moved());
  1782. }
  1783. if (future_obtained)
  1784. {
  1785. boost::throw_exception(future_already_retrieved());
  1786. }
  1787. future_obtained=true;
  1788. return BOOST_THREAD_FUTURE<R>(future_);
  1789. }
  1790. void set_value(typename detail::future_traits<R>::source_reference_type r)
  1791. {
  1792. lazy_init();
  1793. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1794. if(future_->done)
  1795. {
  1796. boost::throw_exception(promise_already_satisfied());
  1797. }
  1798. future_->mark_finished_with_result_internal(r, lock);
  1799. }
  1800. // void set_value(R && r);
  1801. void set_value(typename detail::future_traits<R>::rvalue_source_type r)
  1802. {
  1803. lazy_init();
  1804. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1805. if(future_->done)
  1806. {
  1807. boost::throw_exception(promise_already_satisfied());
  1808. }
  1809. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  1810. future_->mark_finished_with_result_internal(boost::forward<R>(r), lock);
  1811. #else
  1812. future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r), lock);
  1813. #endif
  1814. }
  1815. void set_exception(boost::exception_ptr p)
  1816. {
  1817. lazy_init();
  1818. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1819. if(future_->done)
  1820. {
  1821. boost::throw_exception(promise_already_satisfied());
  1822. }
  1823. future_->mark_exceptional_finish_internal(p, lock);
  1824. }
  1825. template <typename E>
  1826. void set_exception(E ex)
  1827. {
  1828. set_exception(copy_exception(ex));
  1829. }
  1830. // setting the result with deferred notification
  1831. void set_value_at_thread_exit(const R& r)
  1832. {
  1833. if (future_.get()==0)
  1834. {
  1835. boost::throw_exception(promise_moved());
  1836. }
  1837. future_->set_value_at_thread_exit(r);
  1838. }
  1839. void set_value_at_thread_exit(BOOST_THREAD_RV_REF(R) r)
  1840. {
  1841. if (future_.get()==0)
  1842. {
  1843. boost::throw_exception(promise_moved());
  1844. }
  1845. future_->set_value_at_thread_exit(boost::move(r));
  1846. }
  1847. void set_exception_at_thread_exit(exception_ptr e)
  1848. {
  1849. if (future_.get()==0)
  1850. {
  1851. boost::throw_exception(promise_moved());
  1852. }
  1853. future_->set_exception_at_thread_exit(e);
  1854. }
  1855. template <typename E>
  1856. void set_exception_at_thread_exit(E ex)
  1857. {
  1858. set_exception_at_thread_exit(copy_exception(ex));
  1859. }
  1860. template<typename F>
  1861. void set_wait_callback(F f)
  1862. {
  1863. lazy_init();
  1864. future_->set_wait_callback(f,this);
  1865. }
  1866. };
  1867. template <typename R>
  1868. class promise<R&>
  1869. {
  1870. typedef boost::shared_ptr<detail::shared_state<R&> > future_ptr;
  1871. future_ptr future_;
  1872. bool future_obtained;
  1873. void lazy_init()
  1874. {
  1875. #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
  1876. #include <boost/detail/atomic_undef_macros.hpp>
  1877. if(!atomic_load(&future_))
  1878. {
  1879. future_ptr blank;
  1880. atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
  1881. }
  1882. #include <boost/detail/atomic_redef_macros.hpp>
  1883. #endif
  1884. }
  1885. public:
  1886. BOOST_THREAD_MOVABLE_ONLY(promise)
  1887. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  1888. template <class Allocator>
  1889. promise(boost::allocator_arg_t, Allocator a)
  1890. {
  1891. typedef typename Allocator::template rebind<detail::shared_state<R&> >::other A2;
  1892. A2 a2(a);
  1893. typedef thread_detail::allocator_destructor<A2> D;
  1894. future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
  1895. future_obtained = false;
  1896. }
  1897. #endif
  1898. promise():
  1899. #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
  1900. future_(),
  1901. #else
  1902. future_(new detail::shared_state<R&>()),
  1903. #endif
  1904. future_obtained(false)
  1905. {}
  1906. ~promise()
  1907. {
  1908. if(future_)
  1909. {
  1910. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1911. if(!future_->done && !future_->is_constructed)
  1912. {
  1913. future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
  1914. }
  1915. }
  1916. }
  1917. // Assignment
  1918. promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
  1919. future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
  1920. {
  1921. BOOST_THREAD_RV(rhs).future_.reset();
  1922. BOOST_THREAD_RV(rhs).future_obtained=false;
  1923. }
  1924. promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
  1925. {
  1926. future_=BOOST_THREAD_RV(rhs).future_;
  1927. future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
  1928. BOOST_THREAD_RV(rhs).future_.reset();
  1929. BOOST_THREAD_RV(rhs).future_obtained=false;
  1930. return *this;
  1931. }
  1932. void swap(promise& other)
  1933. {
  1934. future_.swap(other.future_);
  1935. std::swap(future_obtained,other.future_obtained);
  1936. }
  1937. // Result retrieval
  1938. BOOST_THREAD_FUTURE<R&> get_future()
  1939. {
  1940. lazy_init();
  1941. if (future_.get()==0)
  1942. {
  1943. boost::throw_exception(promise_moved());
  1944. }
  1945. if (future_obtained)
  1946. {
  1947. boost::throw_exception(future_already_retrieved());
  1948. }
  1949. future_obtained=true;
  1950. return BOOST_THREAD_FUTURE<R&>(future_);
  1951. }
  1952. void set_value(R& r)
  1953. {
  1954. lazy_init();
  1955. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1956. if(future_->done)
  1957. {
  1958. boost::throw_exception(promise_already_satisfied());
  1959. }
  1960. future_->mark_finished_with_result_internal(r, lock);
  1961. }
  1962. void set_exception(boost::exception_ptr p)
  1963. {
  1964. lazy_init();
  1965. boost::unique_lock<boost::mutex> lock(future_->mutex);
  1966. if(future_->done)
  1967. {
  1968. boost::throw_exception(promise_already_satisfied());
  1969. }
  1970. future_->mark_exceptional_finish_internal(p, lock);
  1971. }
  1972. template <typename E>
  1973. void set_exception(E ex)
  1974. {
  1975. set_exception(copy_exception(ex));
  1976. }
  1977. // setting the result with deferred notification
  1978. void set_value_at_thread_exit(R& r)
  1979. {
  1980. if (future_.get()==0)
  1981. {
  1982. boost::throw_exception(promise_moved());
  1983. }
  1984. future_->set_value_at_thread_exit(r);
  1985. }
  1986. void set_exception_at_thread_exit(exception_ptr e)
  1987. {
  1988. if (future_.get()==0)
  1989. {
  1990. boost::throw_exception(promise_moved());
  1991. }
  1992. future_->set_exception_at_thread_exit(e);
  1993. }
  1994. template <typename E>
  1995. void set_exception_at_thread_exit(E ex)
  1996. {
  1997. set_exception_at_thread_exit(copy_exception(ex));
  1998. }
  1999. template<typename F>
  2000. void set_wait_callback(F f)
  2001. {
  2002. lazy_init();
  2003. future_->set_wait_callback(f,this);
  2004. }
  2005. };
  2006. template <>
  2007. class promise<void>
  2008. {
  2009. typedef boost::shared_ptr<detail::shared_state<void> > future_ptr;
  2010. future_ptr future_;
  2011. bool future_obtained;
  2012. void lazy_init()
  2013. {
  2014. #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
  2015. if(!atomic_load(&future_))
  2016. {
  2017. future_ptr blank;
  2018. atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<void>));
  2019. }
  2020. #endif
  2021. }
  2022. public:
  2023. BOOST_THREAD_MOVABLE_ONLY(promise)
  2024. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  2025. template <class Allocator>
  2026. promise(boost::allocator_arg_t, Allocator a)
  2027. {
  2028. typedef typename Allocator::template rebind<detail::shared_state<void> >::other A2;
  2029. A2 a2(a);
  2030. typedef thread_detail::allocator_destructor<A2> D;
  2031. future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
  2032. future_obtained = false;
  2033. }
  2034. #endif
  2035. promise():
  2036. #if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
  2037. future_(),
  2038. #else
  2039. future_(new detail::shared_state<void>),
  2040. #endif
  2041. future_obtained(false)
  2042. {}
  2043. ~promise()
  2044. {
  2045. if(future_)
  2046. {
  2047. boost::unique_lock<boost::mutex> lock(future_->mutex);
  2048. if(!future_->done && !future_->is_constructed)
  2049. {
  2050. future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()), lock);
  2051. }
  2052. }
  2053. }
  2054. // Assignment
  2055. promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT :
  2056. future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)
  2057. {
  2058. // we need to release the future as shared_ptr doesn't implements move semantics
  2059. BOOST_THREAD_RV(rhs).future_.reset();
  2060. BOOST_THREAD_RV(rhs).future_obtained=false;
  2061. }
  2062. promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT
  2063. {
  2064. future_=BOOST_THREAD_RV(rhs).future_;
  2065. future_obtained=BOOST_THREAD_RV(rhs).future_obtained;
  2066. BOOST_THREAD_RV(rhs).future_.reset();
  2067. BOOST_THREAD_RV(rhs).future_obtained=false;
  2068. return *this;
  2069. }
  2070. void swap(promise& other)
  2071. {
  2072. future_.swap(other.future_);
  2073. std::swap(future_obtained,other.future_obtained);
  2074. }
  2075. // Result retrieval
  2076. BOOST_THREAD_FUTURE<void> get_future()
  2077. {
  2078. lazy_init();
  2079. if (future_.get()==0)
  2080. {
  2081. boost::throw_exception(promise_moved());
  2082. }
  2083. if(future_obtained)
  2084. {
  2085. boost::throw_exception(future_already_retrieved());
  2086. }
  2087. future_obtained=true;
  2088. return BOOST_THREAD_FUTURE<void>(future_);
  2089. }
  2090. void set_value()
  2091. {
  2092. lazy_init();
  2093. boost::unique_lock<boost::mutex> lock(future_->mutex);
  2094. if(future_->done)
  2095. {
  2096. boost::throw_exception(promise_already_satisfied());
  2097. }
  2098. future_->mark_finished_with_result_internal(lock);
  2099. }
  2100. void set_exception(boost::exception_ptr p)
  2101. {
  2102. lazy_init();
  2103. boost::unique_lock<boost::mutex> lock(future_->mutex);
  2104. if(future_->done)
  2105. {
  2106. boost::throw_exception(promise_already_satisfied());
  2107. }
  2108. future_->mark_exceptional_finish_internal(p,lock);
  2109. }
  2110. template <typename E>
  2111. void set_exception(E ex)
  2112. {
  2113. set_exception(copy_exception(ex));
  2114. }
  2115. // setting the result with deferred notification
  2116. void set_value_at_thread_exit()
  2117. {
  2118. if (future_.get()==0)
  2119. {
  2120. boost::throw_exception(promise_moved());
  2121. }
  2122. future_->set_value_at_thread_exit();
  2123. }
  2124. void set_exception_at_thread_exit(exception_ptr e)
  2125. {
  2126. if (future_.get()==0)
  2127. {
  2128. boost::throw_exception(promise_moved());
  2129. }
  2130. future_->set_exception_at_thread_exit(e);
  2131. }
  2132. template <typename E>
  2133. void set_exception_at_thread_exit(E ex)
  2134. {
  2135. set_exception_at_thread_exit(copy_exception(ex));
  2136. }
  2137. template<typename F>
  2138. void set_wait_callback(F f)
  2139. {
  2140. lazy_init();
  2141. future_->set_wait_callback(f,this);
  2142. }
  2143. };
  2144. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  2145. namespace container
  2146. {
  2147. template <class R, class Alloc>
  2148. struct uses_allocator<promise<R> , Alloc> : true_type
  2149. {
  2150. };
  2151. }
  2152. #endif
  2153. BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
  2154. namespace detail
  2155. {
  2156. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2157. template<typename R>
  2158. struct task_base_shared_state;
  2159. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2160. template<typename R, typename ...ArgTypes>
  2161. struct task_base_shared_state<R(ArgTypes...)>:
  2162. #else
  2163. template<typename R>
  2164. struct task_base_shared_state<R()>:
  2165. #endif
  2166. #else
  2167. template<typename R>
  2168. struct task_base_shared_state:
  2169. #endif
  2170. detail::shared_state<R>
  2171. {
  2172. bool started;
  2173. task_base_shared_state():
  2174. started(false)
  2175. {}
  2176. void reset()
  2177. {
  2178. started=false;
  2179. }
  2180. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2181. virtual void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
  2182. void run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2183. #else
  2184. virtual void do_run()=0;
  2185. void run()
  2186. #endif
  2187. {
  2188. {
  2189. boost::lock_guard<boost::mutex> lk(this->mutex);
  2190. if(started)
  2191. {
  2192. boost::throw_exception(task_already_started());
  2193. }
  2194. started=true;
  2195. }
  2196. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2197. do_run(boost::forward<ArgTypes>(args)...);
  2198. #else
  2199. do_run();
  2200. #endif
  2201. }
  2202. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2203. virtual void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)=0;
  2204. void apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2205. #else
  2206. virtual void do_apply()=0;
  2207. void apply()
  2208. #endif
  2209. {
  2210. {
  2211. boost::lock_guard<boost::mutex> lk(this->mutex);
  2212. if(started)
  2213. {
  2214. boost::throw_exception(task_already_started());
  2215. }
  2216. started=true;
  2217. }
  2218. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2219. do_apply(boost::forward<ArgTypes>(args)...);
  2220. #else
  2221. do_apply();
  2222. #endif
  2223. }
  2224. void owner_destroyed()
  2225. {
  2226. boost::unique_lock<boost::mutex> lk(this->mutex);
  2227. if(!started)
  2228. {
  2229. started=true;
  2230. this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()), lk);
  2231. }
  2232. }
  2233. };
  2234. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2235. template<typename F, typename R>
  2236. struct task_shared_state;
  2237. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2238. template<typename F, typename R, typename ...ArgTypes>
  2239. struct task_shared_state<F, R(ArgTypes...)>:
  2240. task_base_shared_state<R(ArgTypes...)>
  2241. #else
  2242. template<typename F, typename R>
  2243. struct task_shared_state<F, R()>:
  2244. task_base_shared_state<R()>
  2245. #endif
  2246. #else
  2247. template<typename F, typename R>
  2248. struct task_shared_state:
  2249. task_base_shared_state<R>
  2250. #endif
  2251. {
  2252. private:
  2253. task_shared_state(task_shared_state&);
  2254. public:
  2255. F f;
  2256. task_shared_state(F const& f_):
  2257. f(f_)
  2258. {}
  2259. task_shared_state(BOOST_THREAD_RV_REF(F) f_):
  2260. f(boost::move(f_))
  2261. {}
  2262. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2263. void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2264. {
  2265. try
  2266. {
  2267. this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
  2268. }
  2269. #else
  2270. void do_apply()
  2271. {
  2272. try
  2273. {
  2274. this->set_value_at_thread_exit(f());
  2275. }
  2276. #endif
  2277. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2278. catch(thread_interrupted& )
  2279. {
  2280. this->set_interrupted_at_thread_exit();
  2281. }
  2282. #endif
  2283. catch(...)
  2284. {
  2285. this->set_exception_at_thread_exit(current_exception());
  2286. }
  2287. }
  2288. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2289. void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2290. {
  2291. try
  2292. {
  2293. this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
  2294. }
  2295. #else
  2296. void do_run()
  2297. {
  2298. try
  2299. {
  2300. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  2301. R res((f()));
  2302. this->mark_finished_with_result(boost::move(res));
  2303. #else
  2304. this->mark_finished_with_result(f());
  2305. #endif
  2306. }
  2307. #endif
  2308. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2309. catch(thread_interrupted& )
  2310. {
  2311. this->mark_interrupted_finish();
  2312. }
  2313. #endif
  2314. catch(...)
  2315. {
  2316. this->mark_exceptional_finish();
  2317. }
  2318. }
  2319. };
  2320. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2321. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2322. template<typename F, typename R, typename ...ArgTypes>
  2323. struct task_shared_state<F, R&(ArgTypes...)>:
  2324. task_base_shared_state<R&(ArgTypes...)>
  2325. #else
  2326. template<typename F, typename R>
  2327. struct task_shared_state<F, R&()>:
  2328. task_base_shared_state<R&()>
  2329. #endif
  2330. #else
  2331. template<typename F, typename R>
  2332. struct task_shared_state<F,R&>:
  2333. task_base_shared_state<R&>
  2334. #endif
  2335. {
  2336. private:
  2337. task_shared_state(task_shared_state&);
  2338. public:
  2339. F f;
  2340. task_shared_state(F const& f_):
  2341. f(f_)
  2342. {}
  2343. task_shared_state(BOOST_THREAD_RV_REF(F) f_):
  2344. f(boost::move(f_))
  2345. {}
  2346. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2347. void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2348. {
  2349. try
  2350. {
  2351. this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
  2352. }
  2353. #else
  2354. void do_apply()
  2355. {
  2356. try
  2357. {
  2358. this->set_value_at_thread_exit(f());
  2359. }
  2360. #endif
  2361. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2362. catch(thread_interrupted& )
  2363. {
  2364. this->set_interrupted_at_thread_exit();
  2365. }
  2366. #endif
  2367. catch(...)
  2368. {
  2369. this->set_exception_at_thread_exit(current_exception());
  2370. }
  2371. }
  2372. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2373. void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2374. {
  2375. try
  2376. {
  2377. this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
  2378. }
  2379. #else
  2380. void do_run()
  2381. {
  2382. try
  2383. {
  2384. R& res((f()));
  2385. this->mark_finished_with_result(res);
  2386. }
  2387. #endif
  2388. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2389. catch(thread_interrupted& )
  2390. {
  2391. this->mark_interrupted_finish();
  2392. }
  2393. #endif
  2394. catch(...)
  2395. {
  2396. this->mark_exceptional_finish();
  2397. }
  2398. }
  2399. };
  2400. #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  2401. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2402. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2403. template<typename R, typename ...ArgTypes>
  2404. struct task_shared_state<R (*)(ArgTypes...), R(ArgTypes...)>:
  2405. task_base_shared_state<R(ArgTypes...)>
  2406. #else
  2407. template<typename R>
  2408. struct task_shared_state<R (*)(), R()>:
  2409. task_base_shared_state<R()>
  2410. #endif
  2411. #else
  2412. template<typename R>
  2413. struct task_shared_state<R (*)(), R> :
  2414. task_base_shared_state<R>
  2415. #endif
  2416. {
  2417. private:
  2418. task_shared_state(task_shared_state&);
  2419. public:
  2420. R (*f)();
  2421. task_shared_state(R (*f_)()):
  2422. f(f_)
  2423. {}
  2424. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2425. void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2426. {
  2427. try
  2428. {
  2429. this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
  2430. }
  2431. #else
  2432. void do_apply()
  2433. {
  2434. try
  2435. {
  2436. R r((f()));
  2437. this->set_value_at_thread_exit(boost::move(r));
  2438. }
  2439. #endif
  2440. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2441. catch(thread_interrupted& )
  2442. {
  2443. this->set_interrupted_at_thread_exit();
  2444. }
  2445. #endif
  2446. catch(...)
  2447. {
  2448. this->set_exception_at_thread_exit(current_exception());
  2449. }
  2450. }
  2451. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2452. void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2453. {
  2454. try
  2455. {
  2456. this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
  2457. }
  2458. #else
  2459. void do_run()
  2460. {
  2461. try
  2462. {
  2463. R res((f()));
  2464. this->mark_finished_with_result(boost::move(res));
  2465. }
  2466. #endif
  2467. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2468. catch(thread_interrupted& )
  2469. {
  2470. this->mark_interrupted_finish();
  2471. }
  2472. #endif
  2473. catch(...)
  2474. {
  2475. this->mark_exceptional_finish();
  2476. }
  2477. }
  2478. };
  2479. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2480. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2481. template<typename R, typename ...ArgTypes>
  2482. struct task_shared_state<R& (*)(ArgTypes...), R&(ArgTypes...)>:
  2483. task_base_shared_state<R&(ArgTypes...)>
  2484. #else
  2485. template<typename R>
  2486. struct task_shared_state<R& (*)(), R&()>:
  2487. task_base_shared_state<R&()>
  2488. #endif
  2489. #else
  2490. template<typename R>
  2491. struct task_shared_state<R& (*)(), R&> :
  2492. task_base_shared_state<R&>
  2493. #endif
  2494. {
  2495. private:
  2496. task_shared_state(task_shared_state&);
  2497. public:
  2498. R& (*f)();
  2499. task_shared_state(R& (*f_)()):
  2500. f(f_)
  2501. {}
  2502. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2503. void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2504. {
  2505. try
  2506. {
  2507. this->set_value_at_thread_exit(f(boost::forward<ArgTypes>(args)...));
  2508. }
  2509. #else
  2510. void do_apply()
  2511. {
  2512. try
  2513. {
  2514. this->set_value_at_thread_exit(f());
  2515. }
  2516. #endif
  2517. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2518. catch(thread_interrupted& )
  2519. {
  2520. this->set_interrupted_at_thread_exit();
  2521. }
  2522. #endif
  2523. catch(...)
  2524. {
  2525. this->set_exception_at_thread_exit(current_exception());
  2526. }
  2527. }
  2528. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2529. void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2530. {
  2531. try
  2532. {
  2533. this->mark_finished_with_result(f(boost::forward<ArgTypes>(args)...));
  2534. }
  2535. #else
  2536. void do_run()
  2537. {
  2538. try
  2539. {
  2540. this->mark_finished_with_result(f());
  2541. }
  2542. #endif
  2543. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2544. catch(thread_interrupted& )
  2545. {
  2546. this->mark_interrupted_finish();
  2547. }
  2548. #endif
  2549. catch(...)
  2550. {
  2551. this->mark_exceptional_finish();
  2552. }
  2553. }
  2554. };
  2555. #endif
  2556. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2557. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2558. template<typename F, typename ...ArgTypes>
  2559. struct task_shared_state<F, void(ArgTypes...)>:
  2560. task_base_shared_state<void(ArgTypes...)>
  2561. #else
  2562. template<typename F>
  2563. struct task_shared_state<F, void()>:
  2564. task_base_shared_state<void()>
  2565. #endif
  2566. #else
  2567. template<typename F>
  2568. struct task_shared_state<F,void>:
  2569. task_base_shared_state<void>
  2570. #endif
  2571. {
  2572. private:
  2573. task_shared_state(task_shared_state&);
  2574. public:
  2575. F f;
  2576. task_shared_state(F const& f_):
  2577. f(f_)
  2578. {}
  2579. task_shared_state(BOOST_THREAD_RV_REF(F) f_):
  2580. f(boost::move(f_))
  2581. {}
  2582. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2583. void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2584. {
  2585. try
  2586. {
  2587. f(boost::forward<ArgTypes>(args)...);
  2588. #else
  2589. void do_apply()
  2590. {
  2591. try
  2592. {
  2593. f();
  2594. #endif
  2595. this->set_value_at_thread_exit();
  2596. }
  2597. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2598. catch(thread_interrupted& )
  2599. {
  2600. this->set_interrupted_at_thread_exit();
  2601. }
  2602. #endif
  2603. catch(...)
  2604. {
  2605. this->set_exception_at_thread_exit(current_exception());
  2606. }
  2607. }
  2608. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2609. void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2610. {
  2611. try
  2612. {
  2613. f(boost::forward<ArgTypes>(args)...);
  2614. #else
  2615. void do_run()
  2616. {
  2617. try
  2618. {
  2619. f();
  2620. #endif
  2621. this->mark_finished_with_result();
  2622. }
  2623. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2624. catch(thread_interrupted& )
  2625. {
  2626. this->mark_interrupted_finish();
  2627. }
  2628. #endif
  2629. catch(...)
  2630. {
  2631. this->mark_exceptional_finish();
  2632. }
  2633. }
  2634. };
  2635. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2636. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2637. template<typename ...ArgTypes>
  2638. struct task_shared_state<void (*)(ArgTypes...), void(ArgTypes...)>:
  2639. task_base_shared_state<void(ArgTypes...)>
  2640. #else
  2641. template<>
  2642. struct task_shared_state<void (*)(), void()>:
  2643. task_base_shared_state<void()>
  2644. #endif
  2645. #else
  2646. template<>
  2647. struct task_shared_state<void (*)(),void>:
  2648. task_base_shared_state<void>
  2649. #endif
  2650. {
  2651. private:
  2652. task_shared_state(task_shared_state&);
  2653. public:
  2654. void (*f)();
  2655. task_shared_state(void (*f_)()):
  2656. f(f_)
  2657. {}
  2658. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2659. void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2660. {
  2661. try
  2662. {
  2663. f(boost::forward<ArgTypes>(args)...);
  2664. #else
  2665. void do_apply()
  2666. {
  2667. try
  2668. {
  2669. f();
  2670. #endif
  2671. this->set_value_at_thread_exit();
  2672. }
  2673. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2674. catch(thread_interrupted& )
  2675. {
  2676. this->set_interrupted_at_thread_exit();
  2677. }
  2678. #endif
  2679. catch(...)
  2680. {
  2681. this->set_exception_at_thread_exit(current_exception());
  2682. }
  2683. }
  2684. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2685. void do_run(BOOST_THREAD_RV_REF(ArgTypes) ... args)
  2686. {
  2687. try
  2688. {
  2689. f(boost::forward<ArgTypes>(args)...);
  2690. #else
  2691. void do_run()
  2692. {
  2693. try
  2694. {
  2695. f();
  2696. #endif
  2697. this->mark_finished_with_result();
  2698. }
  2699. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  2700. catch(thread_interrupted& )
  2701. {
  2702. this->mark_interrupted_finish();
  2703. }
  2704. #endif
  2705. catch(...)
  2706. {
  2707. this->mark_exceptional_finish();
  2708. }
  2709. }
  2710. };
  2711. }
  2712. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2713. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2714. template<typename R, typename ...ArgTypes>
  2715. class packaged_task<R(ArgTypes...)>
  2716. {
  2717. typedef boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task_ptr;
  2718. boost::shared_ptr<detail::task_base_shared_state<R(ArgTypes...)> > task;
  2719. #else
  2720. template<typename R>
  2721. class packaged_task<R()>
  2722. {
  2723. typedef boost::shared_ptr<detail::task_base_shared_state<R()> > task_ptr;
  2724. boost::shared_ptr<detail::task_base_shared_state<R()> > task;
  2725. #endif
  2726. #else
  2727. template<typename R>
  2728. class packaged_task
  2729. {
  2730. typedef boost::shared_ptr<detail::task_base_shared_state<R> > task_ptr;
  2731. boost::shared_ptr<detail::task_base_shared_state<R> > task;
  2732. #endif
  2733. bool future_obtained;
  2734. struct dummy;
  2735. public:
  2736. typedef R result_type;
  2737. BOOST_THREAD_MOVABLE_ONLY(packaged_task)
  2738. packaged_task():
  2739. future_obtained(false)
  2740. {}
  2741. // construction and destruction
  2742. #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  2743. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2744. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2745. explicit packaged_task(R(*f)(), BOOST_THREAD_FWD_REF(ArgTypes)... args)
  2746. {
  2747. typedef R(*FR)(BOOST_THREAD_FWD_REF(ArgTypes)...);
  2748. typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
  2749. task= task_ptr(new task_shared_state_type(f, boost::forward<ArgTypes>(args)...));
  2750. future_obtained=false;
  2751. }
  2752. #else
  2753. explicit packaged_task(R(*f)())
  2754. {
  2755. typedef R(*FR)();
  2756. typedef detail::task_shared_state<FR,R()> task_shared_state_type;
  2757. task= task_ptr(new task_shared_state_type(f));
  2758. future_obtained=false;
  2759. }
  2760. #endif
  2761. #else
  2762. explicit packaged_task(R(*f)())
  2763. {
  2764. typedef R(*FR)();
  2765. typedef detail::task_shared_state<FR,R> task_shared_state_type;
  2766. task= task_ptr(new task_shared_state_type(f));
  2767. future_obtained=false;
  2768. }
  2769. #endif
  2770. #endif
  2771. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  2772. template <class F>
  2773. explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
  2774. , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
  2775. )
  2776. {
  2777. typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
  2778. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2779. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2780. typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
  2781. #else
  2782. typedef detail::task_shared_state<FR,R()> task_shared_state_type;
  2783. #endif
  2784. #else
  2785. typedef detail::task_shared_state<FR,R> task_shared_state_type;
  2786. #endif
  2787. task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
  2788. future_obtained = false;
  2789. }
  2790. #else
  2791. template <class F>
  2792. explicit packaged_task(F const& f
  2793. , typename boost::disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
  2794. )
  2795. {
  2796. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2797. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2798. typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
  2799. #else
  2800. typedef detail::task_shared_state<F,R()> task_shared_state_type;
  2801. #endif
  2802. #else
  2803. typedef detail::task_shared_state<F,R> task_shared_state_type;
  2804. #endif
  2805. task = task_ptr(new task_shared_state_type(f));
  2806. future_obtained=false;
  2807. }
  2808. template <class F>
  2809. explicit packaged_task(BOOST_THREAD_RV_REF(F) f)
  2810. {
  2811. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2812. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2813. typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
  2814. task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
  2815. #else
  2816. typedef detail::task_shared_state<F,R()> task_shared_state_type;
  2817. task = task_ptr(new task_shared_state_type(boost::move(f))); // TODO forward
  2818. #endif
  2819. #else
  2820. typedef detail::task_shared_state<F,R> task_shared_state_type;
  2821. task = task_ptr(new task_shared_state_type(boost::forward<F>(f)));
  2822. #endif
  2823. future_obtained=false;
  2824. }
  2825. #endif
  2826. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  2827. #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  2828. template <class Allocator>
  2829. packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
  2830. {
  2831. typedef R(*FR)();
  2832. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2833. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2834. typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
  2835. #else
  2836. typedef detail::task_shared_state<FR,R()> task_shared_state_type;
  2837. #endif
  2838. #else
  2839. typedef detail::task_shared_state<FR,R> task_shared_state_type;
  2840. #endif
  2841. typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
  2842. A2 a2(a);
  2843. typedef thread_detail::allocator_destructor<A2> D;
  2844. task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
  2845. future_obtained = false;
  2846. }
  2847. #endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
  2848. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  2849. template <class F, class Allocator>
  2850. packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
  2851. {
  2852. typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
  2853. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2854. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2855. typedef detail::task_shared_state<FR,R(ArgTypes...)> task_shared_state_type;
  2856. #else
  2857. typedef detail::task_shared_state<FR,R()> task_shared_state_type;
  2858. #endif
  2859. #else
  2860. typedef detail::task_shared_state<FR,R> task_shared_state_type;
  2861. #endif
  2862. typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
  2863. A2 a2(a);
  2864. typedef thread_detail::allocator_destructor<A2> D;
  2865. task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
  2866. future_obtained = false;
  2867. }
  2868. #else // ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  2869. template <class F, class Allocator>
  2870. packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
  2871. {
  2872. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2873. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2874. typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
  2875. #else
  2876. typedef detail::task_shared_state<F,R()> task_shared_state_type;
  2877. #endif
  2878. #else
  2879. typedef detail::task_shared_state<F,R> task_shared_state_type;
  2880. #endif
  2881. typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
  2882. A2 a2(a);
  2883. typedef thread_detail::allocator_destructor<A2> D;
  2884. task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
  2885. future_obtained = false;
  2886. }
  2887. template <class F, class Allocator>
  2888. packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
  2889. {
  2890. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  2891. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2892. typedef detail::task_shared_state<F,R(ArgTypes...)> task_shared_state_type;
  2893. #else
  2894. typedef detail::task_shared_state<F,R()> task_shared_state_type;
  2895. #endif
  2896. #else
  2897. typedef detail::task_shared_state<F,R> task_shared_state_type;
  2898. #endif
  2899. typedef typename Allocator::template rebind<task_shared_state_type>::other A2;
  2900. A2 a2(a);
  2901. typedef thread_detail::allocator_destructor<A2> D;
  2902. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2903. task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::forward<F>(f)), D(a2, 1) );
  2904. #else
  2905. task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(boost::move(f)), D(a2, 1) ); // TODO forward
  2906. #endif
  2907. future_obtained = false;
  2908. }
  2909. #endif //BOOST_NO_CXX11_RVALUE_REFERENCES
  2910. #endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  2911. ~packaged_task()
  2912. {
  2913. if(task)
  2914. {
  2915. task->owner_destroyed();
  2916. }
  2917. }
  2918. // assignment
  2919. packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT :
  2920. future_obtained(BOOST_THREAD_RV(other).future_obtained)
  2921. {
  2922. task.swap(BOOST_THREAD_RV(other).task);
  2923. BOOST_THREAD_RV(other).future_obtained=false;
  2924. }
  2925. packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT
  2926. {
  2927. // todo use forward
  2928. #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
  2929. packaged_task temp(boost::move(other));
  2930. #else
  2931. packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));
  2932. #endif
  2933. swap(temp);
  2934. return *this;
  2935. }
  2936. void reset()
  2937. {
  2938. if (!valid())
  2939. throw future_error(system::make_error_code(future_errc::no_state));
  2940. task->reset();
  2941. future_obtained=false;
  2942. }
  2943. void swap(packaged_task& other) BOOST_NOEXCEPT
  2944. {
  2945. task.swap(other.task);
  2946. std::swap(future_obtained,other.future_obtained);
  2947. }
  2948. bool valid() const BOOST_NOEXCEPT
  2949. {
  2950. return task.get()!=0;
  2951. }
  2952. // result retrieval
  2953. BOOST_THREAD_FUTURE<R> get_future()
  2954. {
  2955. if(!task)
  2956. {
  2957. boost::throw_exception(task_moved());
  2958. }
  2959. else if(!future_obtained)
  2960. {
  2961. future_obtained=true;
  2962. return BOOST_THREAD_FUTURE<R>(task);
  2963. }
  2964. else
  2965. {
  2966. boost::throw_exception(future_already_retrieved());
  2967. }
  2968. //return BOOST_THREAD_FUTURE<R>();
  2969. }
  2970. // execution
  2971. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  2972. void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args)
  2973. {
  2974. if(!task)
  2975. {
  2976. boost::throw_exception(task_moved());
  2977. }
  2978. task->run(boost::forward<ArgTypes>(args)...);
  2979. }
  2980. void make_ready_at_thread_exit(ArgTypes... args)
  2981. {
  2982. if(!task)
  2983. {
  2984. boost::throw_exception(task_moved());
  2985. }
  2986. if (task->has_value())
  2987. {
  2988. boost::throw_exception(promise_already_satisfied());
  2989. }
  2990. task->apply(boost::forward<ArgTypes>(args)...);
  2991. }
  2992. #else
  2993. void operator()()
  2994. {
  2995. if(!task)
  2996. {
  2997. boost::throw_exception(task_moved());
  2998. }
  2999. task->run();
  3000. }
  3001. void make_ready_at_thread_exit()
  3002. {
  3003. if(!task)
  3004. {
  3005. boost::throw_exception(task_moved());
  3006. }
  3007. if (task->has_value())
  3008. boost::throw_exception(promise_already_satisfied());
  3009. task->apply();
  3010. }
  3011. #endif
  3012. template<typename F>
  3013. void set_wait_callback(F f)
  3014. {
  3015. task->set_wait_callback(f,this);
  3016. }
  3017. };
  3018. #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
  3019. namespace container
  3020. {
  3021. template <class R, class Alloc>
  3022. struct uses_allocator<packaged_task<R>, Alloc>
  3023. : public true_type {};
  3024. }
  3025. #endif
  3026. BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
  3027. namespace detail
  3028. {
  3029. ////////////////////////////////
  3030. // make_future_deferred_shared_state
  3031. ////////////////////////////////
  3032. template <class Rp, class Fp>
  3033. BOOST_THREAD_FUTURE<Rp>
  3034. make_future_deferred_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
  3035. {
  3036. shared_ptr<future_deferred_shared_state<Rp, Fp> >
  3037. h(new future_deferred_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
  3038. return BOOST_THREAD_FUTURE<Rp>(h);
  3039. }
  3040. ////////////////////////////////
  3041. // make_future_async_shared_state
  3042. ////////////////////////////////
  3043. template <class Rp, class Fp>
  3044. BOOST_THREAD_FUTURE<Rp>
  3045. make_future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
  3046. {
  3047. shared_ptr<future_async_shared_state<Rp, Fp> >
  3048. h(new future_async_shared_state<Rp, Fp>(boost::forward<Fp>(f)));
  3049. return BOOST_THREAD_FUTURE<Rp>(h);
  3050. }
  3051. }
  3052. ////////////////////////////////
  3053. // template <class F, class... ArgTypes>
  3054. // future<R> async(launch policy, F&&, ArgTypes&&...);
  3055. ////////////////////////////////
  3056. #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
  3057. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  3058. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3059. template <class R, class... ArgTypes>
  3060. BOOST_THREAD_FUTURE<R>
  3061. async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
  3062. {
  3063. typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
  3064. typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
  3065. typedef typename BF::result_type Rp;
  3066. #else
  3067. template <class R>
  3068. BOOST_THREAD_FUTURE<R>
  3069. async(launch policy, R(*f)())
  3070. {
  3071. typedef packaged_task<R()> packaged_task_type;
  3072. #endif
  3073. #else
  3074. template <class R>
  3075. BOOST_THREAD_FUTURE<R>
  3076. async(launch policy, R(*f)())
  3077. {
  3078. typedef packaged_task<R> packaged_task_type;
  3079. #endif
  3080. if (int(policy) & int(launch::async))
  3081. {
  3082. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3083. return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
  3084. BF(
  3085. thread_detail::decay_copy(boost::forward<F>(f))
  3086. , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
  3087. )
  3088. ));
  3089. #else
  3090. packaged_task_type pt( f );
  3091. BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
  3092. ret.set_async();
  3093. boost::thread( boost::move(pt) ).detach();
  3094. return ::boost::move(ret);
  3095. #endif
  3096. }
  3097. else if (int(policy) & int(launch::deferred))
  3098. {
  3099. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3100. return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
  3101. BF(
  3102. thread_detail::decay_copy(boost::forward<F>(f))
  3103. , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
  3104. )
  3105. ));
  3106. #else
  3107. std::terminate();
  3108. BOOST_THREAD_FUTURE<R> ret;
  3109. return ::boost::move(ret);
  3110. #endif
  3111. } else {
  3112. std::terminate();
  3113. BOOST_THREAD_FUTURE<R> ret;
  3114. return ::boost::move(ret);
  3115. }
  3116. }
  3117. #endif
  3118. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  3119. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3120. template <class F, class ...ArgTypes>
  3121. BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
  3122. typename decay<ArgTypes>::type...
  3123. )>::type>
  3124. async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
  3125. {
  3126. typedef typename boost::result_of<typename decay<F>::type(
  3127. typename decay<ArgTypes>::type...
  3128. )>::type R;
  3129. typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
  3130. typedef typename BF::result_type Rp;
  3131. #else
  3132. template <class F>
  3133. BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
  3134. async(launch policy, BOOST_THREAD_FWD_REF(F) f)
  3135. {
  3136. typedef typename boost::result_of<typename decay<F>::type()>::type R;
  3137. typedef packaged_task<R()> packaged_task_type;
  3138. #endif
  3139. #else
  3140. template <class F>
  3141. BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
  3142. async(launch policy, BOOST_THREAD_FWD_REF(F) f)
  3143. {
  3144. typedef typename boost::result_of<typename decay<F>::type()>::type R;
  3145. typedef packaged_task<R> packaged_task_type;
  3146. #endif
  3147. if (int(policy) & int(launch::async))
  3148. {
  3149. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3150. return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_shared_state<Rp>(
  3151. BF(
  3152. thread_detail::decay_copy(boost::forward<F>(f))
  3153. , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
  3154. )
  3155. ));
  3156. #else
  3157. packaged_task_type pt( boost::forward<F>(f) );
  3158. BOOST_THREAD_FUTURE<R> ret = pt.get_future();
  3159. ret.set_async();
  3160. boost::thread( boost::move(pt) ).detach();
  3161. return ::boost::move(ret);
  3162. #endif
  3163. }
  3164. else if (int(policy) & int(launch::deferred))
  3165. {
  3166. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3167. return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_shared_state<Rp>(
  3168. BF(
  3169. thread_detail::decay_copy(boost::forward<F>(f))
  3170. , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
  3171. )
  3172. ));
  3173. #else
  3174. std::terminate();
  3175. BOOST_THREAD_FUTURE<R> ret;
  3176. return ::boost::move(ret);
  3177. // return boost::detail::make_future_deferred_shared_state<Rp>(
  3178. // BF(
  3179. // thread_detail::decay_copy(boost::forward<F>(f))
  3180. // )
  3181. // );
  3182. #endif
  3183. } else {
  3184. std::terminate();
  3185. BOOST_THREAD_FUTURE<R> ret;
  3186. return ::boost::move(ret);
  3187. }
  3188. }
  3189. ////////////////////////////////
  3190. // template <class F, class... ArgTypes>
  3191. // future<R> async(F&&, ArgTypes&&...);
  3192. ////////////////////////////////
  3193. #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
  3194. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3195. template <class R, class... ArgTypes>
  3196. BOOST_THREAD_FUTURE<R>
  3197. async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
  3198. {
  3199. return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
  3200. }
  3201. #else
  3202. template <class R>
  3203. BOOST_THREAD_FUTURE<R>
  3204. async(R(*f)())
  3205. {
  3206. return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
  3207. }
  3208. #endif
  3209. #endif
  3210. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  3211. template <class F, class ...ArgTypes>
  3212. BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
  3213. typename decay<ArgTypes>::type...
  3214. )>::type>
  3215. async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
  3216. {
  3217. return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
  3218. }
  3219. #else
  3220. template <class F>
  3221. BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
  3222. async(BOOST_THREAD_RV_REF(F) f)
  3223. {
  3224. return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
  3225. }
  3226. #endif
  3227. ////////////////////////////////
  3228. // make_future deprecated
  3229. ////////////////////////////////
  3230. template <typename T>
  3231. BOOST_THREAD_FUTURE<typename decay<T>::type> make_future(BOOST_THREAD_FWD_REF(T) value)
  3232. {
  3233. typedef typename decay<T>::type future_value_type;
  3234. promise<future_value_type> p;
  3235. p.set_value(boost::forward<future_value_type>(value));
  3236. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3237. }
  3238. #if defined BOOST_THREAD_USES_MOVE
  3239. inline BOOST_THREAD_FUTURE<void> make_future()
  3240. {
  3241. promise<void> p;
  3242. p.set_value();
  3243. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3244. }
  3245. #endif
  3246. ////////////////////////////////
  3247. // make_ready_future
  3248. ////////////////////////////////
  3249. template <typename T>
  3250. BOOST_THREAD_FUTURE<typename decay<T>::type> make_ready_future(BOOST_THREAD_FWD_REF(T) value)
  3251. {
  3252. typedef typename decay<T>::type future_value_type;
  3253. promise<future_value_type> p;
  3254. p.set_value(boost::forward<future_value_type>(value));
  3255. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3256. }
  3257. #if defined BOOST_THREAD_USES_MOVE
  3258. inline BOOST_THREAD_FUTURE<void> make_ready_future()
  3259. {
  3260. promise<void> p;
  3261. p.set_value();
  3262. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3263. }
  3264. #endif
  3265. template <typename T>
  3266. BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex)
  3267. {
  3268. promise<T> p;
  3269. p.set_exception(ex);
  3270. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3271. }
  3272. template <typename T, typename E>
  3273. BOOST_THREAD_FUTURE<T> make_ready_future(E ex)
  3274. {
  3275. promise<T> p;
  3276. p.set_exception(boost::copy_exception(ex));
  3277. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3278. }
  3279. #if 0
  3280. template<typename CLOSURE>
  3281. make_future(CLOSURE closure) -> BOOST_THREAD_FUTURE<decltype(closure())> {
  3282. typedef decltype(closure()) T;
  3283. promise<T> p;
  3284. try
  3285. {
  3286. p.set_value(closure());
  3287. }
  3288. catch(...)
  3289. {
  3290. p.set_exception(std::current_exception());
  3291. }
  3292. return BOOST_THREAD_MAKE_RV_REF(p.get_future());
  3293. }
  3294. #endif
  3295. ////////////////////////////////
  3296. // make_shared_future deprecated
  3297. ////////////////////////////////
  3298. template <typename T>
  3299. shared_future<typename decay<T>::type> make_shared_future(BOOST_THREAD_FWD_REF(T) value)
  3300. {
  3301. typedef typename decay<T>::type future_type;
  3302. promise<future_type> p;
  3303. p.set_value(boost::forward<T>(value));
  3304. return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
  3305. }
  3306. inline shared_future<void> make_shared_future()
  3307. {
  3308. promise<void> p;
  3309. return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
  3310. }
  3311. // ////////////////////////////////
  3312. // // make_ready_shared_future
  3313. // ////////////////////////////////
  3314. // template <typename T>
  3315. // shared_future<typename decay<T>::type> make_ready_shared_future(BOOST_THREAD_FWD_REF(T) value)
  3316. // {
  3317. // typedef typename decay<T>::type future_type;
  3318. // promise<future_type> p;
  3319. // p.set_value(boost::forward<T>(value));
  3320. // return p.get_future().share();
  3321. // }
  3322. //
  3323. //
  3324. // inline shared_future<void> make_ready_shared_future()
  3325. // {
  3326. // promise<void> p;
  3327. // return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
  3328. //
  3329. // }
  3330. //
  3331. // ////////////////////////////////
  3332. // // make_exceptional_shared_future
  3333. // ////////////////////////////////
  3334. // template <typename T>
  3335. // shared_future<T> make_exceptional_shared_future(exception_ptr ex)
  3336. // {
  3337. // promise<T> p;
  3338. // p.set_exception(ex);
  3339. // return p.get_future().share();
  3340. // }
  3341. ////////////////////////////////
  3342. // detail::future_async_continuation_shared_state
  3343. ////////////////////////////////
  3344. #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
  3345. namespace detail
  3346. {
  3347. /////////////////////////
  3348. /// future_async_continuation_shared_state
  3349. /////////////////////////
  3350. template<typename F, typename Rp, typename Fp>
  3351. struct future_async_continuation_shared_state: future_async_shared_state_base<Rp>
  3352. {
  3353. F parent;
  3354. Fp continuation;
  3355. public:
  3356. future_async_continuation_shared_state(
  3357. BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
  3358. ) :
  3359. parent(boost::move(f)),
  3360. continuation(boost::move(c))
  3361. {
  3362. }
  3363. void launch_continuation(boost::unique_lock<boost::mutex>& lock)
  3364. {
  3365. lock.unlock();
  3366. this->thr_ = thread(&future_async_continuation_shared_state::run, this);
  3367. }
  3368. static void run(future_async_continuation_shared_state* that)
  3369. {
  3370. try
  3371. {
  3372. that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
  3373. }
  3374. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  3375. catch(thread_interrupted& )
  3376. {
  3377. that->mark_interrupted_finish();
  3378. }
  3379. #endif
  3380. catch(...)
  3381. {
  3382. that->mark_exceptional_finish();
  3383. }
  3384. }
  3385. ~future_async_continuation_shared_state()
  3386. {
  3387. this->join();
  3388. }
  3389. };
  3390. template<typename F, typename Fp>
  3391. struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
  3392. {
  3393. F parent;
  3394. Fp continuation;
  3395. public:
  3396. future_async_continuation_shared_state(
  3397. BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
  3398. ) :
  3399. parent(boost::move(f)),
  3400. continuation(boost::move(c))
  3401. {
  3402. }
  3403. void launch_continuation(boost::unique_lock<boost::mutex>& lk)
  3404. {
  3405. lk.unlock();
  3406. this->thr_ = thread(&future_async_continuation_shared_state::run, this);
  3407. }
  3408. static void run(future_async_continuation_shared_state* that)
  3409. {
  3410. try
  3411. {
  3412. that->continuation(boost::move(that->parent));
  3413. that->mark_finished_with_result();
  3414. }
  3415. #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
  3416. catch(thread_interrupted& )
  3417. {
  3418. that->mark_interrupted_finish();
  3419. }
  3420. #endif
  3421. catch(...)
  3422. {
  3423. that->mark_exceptional_finish();
  3424. }
  3425. }
  3426. ~future_async_continuation_shared_state()
  3427. {
  3428. this->join();
  3429. }
  3430. };
  3431. //////////////////////////
  3432. /// future_deferred_continuation_shared_state
  3433. //////////////////////////
  3434. template<typename F, typename Rp, typename Fp>
  3435. struct future_deferred_continuation_shared_state: shared_state<Rp>
  3436. {
  3437. F parent;
  3438. Fp continuation;
  3439. public:
  3440. future_deferred_continuation_shared_state(
  3441. BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
  3442. ) :
  3443. parent(boost::move(f)),
  3444. continuation(boost::move(c))
  3445. {
  3446. this->set_deferred();
  3447. }
  3448. virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk)
  3449. {
  3450. execute(lk);
  3451. }
  3452. virtual void execute(boost::unique_lock<boost::mutex>& lck) {
  3453. try
  3454. {
  3455. Fp local_fuct=boost::move(continuation);
  3456. F ftmp = boost::move(parent);
  3457. relocker relock(lck);
  3458. Rp res = local_fuct(boost::move(ftmp));
  3459. relock.lock();
  3460. this->mark_finished_with_result_internal(boost::move(res), lck);
  3461. }
  3462. catch (...)
  3463. {
  3464. this->mark_exceptional_finish_internal(current_exception(), lck);
  3465. }
  3466. }
  3467. };
  3468. template<typename F, typename Fp>
  3469. struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
  3470. {
  3471. F parent;
  3472. Fp continuation;
  3473. public:
  3474. future_deferred_continuation_shared_state(
  3475. BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
  3476. ):
  3477. parent(boost::move(f)),
  3478. continuation(boost::move(c))
  3479. {
  3480. this->set_deferred();
  3481. }
  3482. virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk)
  3483. {
  3484. execute(lk);
  3485. }
  3486. virtual void execute(boost::unique_lock<boost::mutex>& lck) {
  3487. try
  3488. {
  3489. Fp local_fuct=boost::move(continuation);
  3490. F ftmp = boost::move(parent);
  3491. relocker relock(lck);
  3492. local_fuct(boost::move(ftmp));
  3493. relock.lock();
  3494. this->mark_finished_with_result_internal(lck);
  3495. }
  3496. catch (...)
  3497. {
  3498. this->mark_exceptional_finish_internal(current_exception(), lck);
  3499. }
  3500. }
  3501. };
  3502. ////////////////////////////////
  3503. // make_future_deferred_continuation_shared_state
  3504. ////////////////////////////////
  3505. template<typename F, typename Rp, typename Fp>
  3506. BOOST_THREAD_FUTURE<Rp>
  3507. make_future_deferred_continuation_shared_state(
  3508. boost::unique_lock<boost::mutex> &lock,
  3509. BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
  3510. )
  3511. {
  3512. shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> >
  3513. h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
  3514. h->parent.future_->set_continuation_ptr(h, lock);
  3515. return BOOST_THREAD_FUTURE<Rp>(h);
  3516. }
  3517. ////////////////////////////////
  3518. // make_future_async_continuation_shared_state
  3519. ////////////////////////////////
  3520. template<typename F, typename Rp, typename Fp>
  3521. BOOST_THREAD_FUTURE<Rp>
  3522. make_future_async_continuation_shared_state(
  3523. boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c
  3524. )
  3525. {
  3526. shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> >
  3527. h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
  3528. h->parent.future_->set_continuation_ptr(h, lock);
  3529. return BOOST_THREAD_FUTURE<Rp>(h);
  3530. }
  3531. }
  3532. ////////////////////////////////
  3533. // template<typename F>
  3534. // auto future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
  3535. ////////////////////////////////
  3536. template <typename R>
  3537. template <typename F>
  3538. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
  3539. BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func)
  3540. {
  3541. typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
  3542. BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
  3543. boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3544. if (int(policy) & int(launch::async))
  3545. {
  3546. return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
  3547. lock, boost::move(*this), boost::forward<F>(func)
  3548. )));
  3549. }
  3550. else if (int(policy) & int(launch::deferred))
  3551. {
  3552. return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
  3553. lock, boost::move(*this), boost::forward<F>(func)
  3554. )));
  3555. }
  3556. else
  3557. {
  3558. return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
  3559. lock, boost::move(*this), boost::forward<F>(func)
  3560. )));
  3561. }
  3562. }
  3563. template <typename R>
  3564. template <typename F>
  3565. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
  3566. BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func)
  3567. {
  3568. typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
  3569. BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
  3570. boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3571. if (int(this->launch_policy(lock)) & int(launch::async))
  3572. {
  3573. return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
  3574. lock, boost::move(*this), boost::forward<F>(func)
  3575. );
  3576. }
  3577. else if (int(this->launch_policy(lock)) & int(launch::deferred))
  3578. {
  3579. this->future_->wait_internal(lock);
  3580. return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
  3581. lock, boost::move(*this), boost::forward<F>(func)
  3582. );
  3583. }
  3584. else
  3585. {
  3586. return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
  3587. lock, boost::move(*this), boost::forward<F>(func)
  3588. );
  3589. }
  3590. }
  3591. //#if 0 && defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
  3592. // template <typename R>
  3593. // template<typename RF>
  3594. // BOOST_THREAD_FUTURE<RF>
  3595. // BOOST_THREAD_FUTURE<R>::then(RF(*func)(BOOST_THREAD_FUTURE<R>&))
  3596. // {
  3597. //
  3598. // typedef RF future_type;
  3599. //
  3600. // if (this->future_)
  3601. // {
  3602. // boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3603. // detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
  3604. // new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func);
  3605. // if (ptr==0)
  3606. // {
  3607. // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
  3608. // }
  3609. // this->future_->set_continuation_ptr(ptr, lock);
  3610. // return ptr->get_future();
  3611. // } else {
  3612. // // fixme what to do when the future has no associated state?
  3613. // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
  3614. // }
  3615. //
  3616. // }
  3617. // template <typename R>
  3618. // template<typename RF>
  3619. // BOOST_THREAD_FUTURE<RF>
  3620. // BOOST_THREAD_FUTURE<R>::then(launch policy, RF(*func)(BOOST_THREAD_FUTURE<R>&))
  3621. // {
  3622. //
  3623. // typedef RF future_type;
  3624. //
  3625. // if (this->future_)
  3626. // {
  3627. // boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3628. // detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
  3629. // new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy);
  3630. // if (ptr==0)
  3631. // {
  3632. // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
  3633. // }
  3634. // this->future_->set_continuation_ptr(ptr, lock);
  3635. // return ptr->get_future();
  3636. // } else {
  3637. // // fixme what to do when the future has no associated state?
  3638. // return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
  3639. // }
  3640. //
  3641. // }
  3642. //#endif
  3643. template <typename R>
  3644. template <typename F>
  3645. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
  3646. shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func)
  3647. {
  3648. typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
  3649. BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
  3650. boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3651. if (int(policy) & int(launch::async))
  3652. {
  3653. return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
  3654. lock, boost::move(*this), boost::forward<F>(func)
  3655. )));
  3656. }
  3657. else if (int(policy) & int(launch::deferred))
  3658. {
  3659. return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
  3660. lock, boost::move(*this), boost::forward<F>(func)
  3661. )));
  3662. }
  3663. else
  3664. {
  3665. return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
  3666. lock, boost::move(*this), boost::forward<F>(func)
  3667. )));
  3668. }
  3669. }
  3670. template <typename R>
  3671. template <typename F>
  3672. inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
  3673. shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func)
  3674. {
  3675. typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
  3676. BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
  3677. boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3678. if (int(this->launch_policy(lock)) & int(launch::async))
  3679. {
  3680. return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
  3681. lock, boost::move(*this), boost::forward<F>(func)
  3682. );
  3683. }
  3684. else if (int(this->launch_policy(lock)) & int(launch::deferred))
  3685. {
  3686. this->future_->wait_internal(lock);
  3687. return boost::detail::make_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
  3688. lock, boost::move(*this), boost::forward<F>(func)
  3689. );
  3690. }
  3691. else
  3692. {
  3693. return boost::detail::make_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
  3694. lock, boost::move(*this), boost::forward<F>(func)
  3695. );
  3696. }
  3697. }
  3698. namespace detail
  3699. {
  3700. template <typename T>
  3701. struct mfallbacker_to
  3702. {
  3703. T value_;
  3704. typedef T result_type;
  3705. mfallbacker_to(BOOST_THREAD_RV_REF(T) v)
  3706. : value_(boost::move(v))
  3707. {}
  3708. T operator()(BOOST_THREAD_FUTURE<T> fut)
  3709. {
  3710. return fut.get_or(boost::move(value_));
  3711. }
  3712. };
  3713. template <typename T>
  3714. struct cfallbacker_to
  3715. {
  3716. T value_;
  3717. typedef T result_type;
  3718. cfallbacker_to(T const& v)
  3719. : value_(v)
  3720. {}
  3721. T operator()(BOOST_THREAD_FUTURE<T> fut)
  3722. {
  3723. return fut.get_or(value_);
  3724. }
  3725. };
  3726. }
  3727. ////////////////////////////////
  3728. // future<R> future<R>::fallback_to(R&& v);
  3729. ////////////////////////////////
  3730. template <typename R>
  3731. template <typename R2>
  3732. inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
  3733. BOOST_THREAD_FUTURE<R>::fallback_to(BOOST_THREAD_RV_REF(R2) v)
  3734. {
  3735. return then(detail::mfallbacker_to<R>(boost::move(v)));
  3736. }
  3737. template <typename R>
  3738. template <typename R2>
  3739. inline typename boost::disable_if< is_void<R2>, BOOST_THREAD_FUTURE<R> >::type
  3740. BOOST_THREAD_FUTURE<R>::fallback_to(R2 const& v)
  3741. {
  3742. return then(detail::cfallbacker_to<R>(v));
  3743. }
  3744. #endif
  3745. #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
  3746. namespace detail
  3747. {
  3748. /////////////////////////
  3749. /// future_unwrap_shared_state
  3750. /////////////////////////
  3751. template<typename F, typename Rp>
  3752. struct future_unwrap_shared_state: shared_state<Rp>
  3753. {
  3754. F parent;
  3755. public:
  3756. explicit future_unwrap_shared_state(
  3757. BOOST_THREAD_RV_REF(F) f
  3758. ) :
  3759. parent(boost::move(f))
  3760. {
  3761. }
  3762. virtual void wait(bool ) // todo see if rethrow must be used
  3763. {
  3764. boost::unique_lock<boost::mutex> lock(mutex);
  3765. parent.get().wait();
  3766. }
  3767. virtual Rp get()
  3768. {
  3769. boost::unique_lock<boost::mutex> lock(mutex);
  3770. return parent.get().get();
  3771. }
  3772. };
  3773. template <class F, class Rp>
  3774. BOOST_THREAD_FUTURE<Rp>
  3775. make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f)
  3776. {
  3777. shared_ptr<future_unwrap_shared_state<F, Rp> >
  3778. h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
  3779. h->parent.future_->set_continuation_ptr(h, lock);
  3780. return BOOST_THREAD_FUTURE<Rp>(h);
  3781. }
  3782. }
  3783. template <typename R>
  3784. inline BOOST_THREAD_FUTURE<R>::BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other):
  3785. base_type(other.unwrap())
  3786. {
  3787. }
  3788. template <typename R2>
  3789. BOOST_THREAD_FUTURE<R2>
  3790. BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
  3791. {
  3792. BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
  3793. boost::unique_lock<boost::mutex> lock(this->future_->mutex);
  3794. return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
  3795. }
  3796. #endif
  3797. }
  3798. #endif // BOOST_NO_EXCEPTION
  3799. #endif // header