future
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _GLIBCXX_FUTURE
00030 #define _GLIBCXX_FUTURE 1
00031
00032 #pragma GCC system_header
00033
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <c++0x_warning.h>
00036 #else
00037
00038 #include <functional>
00039 #include <memory>
00040 #include <mutex>
00041 #include <condition_variable>
00042 #include <system_error>
00043 #include <exception>
00044 #include <atomic>
00045 #include <bits/functexcept.h>
00046
00047 namespace std
00048 {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 enum class future_errc
00059 { broken_promise, future_already_retrieved, promise_already_satisfied };
00060
00061
00062
00063 template<>
00064 struct is_error_code_enum<future_errc> : public true_type { };
00065
00066
00067 extern const error_category* const future_category;
00068
00069
00070 inline error_code make_error_code(future_errc __errc)
00071 { return error_code(static_cast<int>(__errc), *future_category); }
00072
00073
00074 inline error_condition make_error_condition(future_errc __errc)
00075 { return error_condition(static_cast<int>(__errc), *future_category); }
00076
00077
00078
00079
00080
00081 class future_error : public logic_error
00082 {
00083 error_code _M_code;
00084
00085 public:
00086 explicit future_error(future_errc __ec)
00087 : logic_error("std::future_error"), _M_code(make_error_code(__ec))
00088 { }
00089
00090 virtual ~future_error() throw();
00091
00092 virtual const char*
00093 what() const throw();
00094
00095 const error_code&
00096 code() const throw() { return _M_code; }
00097 };
00098
00099
00100 template<typename _Res>
00101 class unique_future;
00102
00103 template<typename _Res>
00104 class shared_future;
00105
00106 template<typename>
00107 class packaged_task;
00108
00109 template<typename _Res>
00110 class promise;
00111
00112 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
00113 && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
00114
00115
00116 struct __future_base
00117 {
00118
00119 struct _Result_base
00120 {
00121 exception_ptr _M_error;
00122
00123 _Result_base() = default;
00124 _Result_base(const _Result_base&) = delete;
00125 _Result_base& operator=(const _Result_base&) = delete;
00126
00127
00128
00129
00130 virtual void _M_destroy() = 0;
00131
00132 struct _Deleter
00133 {
00134 void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
00135 };
00136
00137 protected:
00138 ~_Result_base();
00139 };
00140
00141
00142 template<typename _Res>
00143 struct _Result : _Result_base
00144 {
00145 private:
00146 typedef alignment_of<_Res> __a_of;
00147 typedef aligned_storage<sizeof(_Res), __a_of::value> __align_storage;
00148 typedef typename __align_storage::type __align_type;
00149
00150 __align_type _M_storage;
00151 bool _M_initialized;
00152
00153 public:
00154 _Result() : _M_initialized() { }
00155
00156 ~_Result()
00157 {
00158 if (_M_initialized)
00159 _M_value().~_Res();
00160 }
00161
00162
00163 _Res&
00164 _M_value() { return *static_cast<_Res*>(_M_addr()); }
00165
00166 void
00167 _M_set(const _Res& __res)
00168 {
00169 ::new (_M_addr()) _Res(__res);
00170 _M_initialized = true;
00171 }
00172
00173 void
00174 _M_set(_Res&& __res)
00175 {
00176 ::new (_M_addr()) _Res(std::move(__res));
00177 _M_initialized = true;
00178 }
00179
00180 private:
00181 void _M_destroy() { delete this; }
00182
00183 void* _M_addr() { return static_cast<void*>(&_M_storage); }
00184 };
00185
00186
00187
00188
00189
00190
00191
00192
00193 template<typename _Res>
00194 struct _Ptr
00195 {
00196 typedef unique_ptr<_Res, _Result_base::_Deleter> type;
00197 };
00198
00199
00200
00201 class _State
00202 {
00203 typedef _Ptr<_Result_base>::type _Ptr_type;
00204
00205 _Ptr_type _M_result;
00206 mutex _M_mutex;
00207 condition_variable _M_cond;
00208 atomic_flag _M_retrieved;
00209
00210 public:
00211 _State() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
00212
00213 _State(const _State&) = delete;
00214 _State& operator=(const _State&) = delete;
00215
00216 bool
00217 is_ready()
00218 { return _M_get() != 0; }
00219
00220 bool
00221 has_exception()
00222 {
00223 _Result_base* const __res = _M_get();
00224 return __res && !(__res->_M_error == 0);
00225 }
00226
00227 bool
00228 has_value()
00229 {
00230 _Result_base* const __res = _M_get();
00231 return __res && (__res->_M_error == 0);
00232 }
00233
00234 _Result_base&
00235 wait()
00236 {
00237 unique_lock<mutex> __lock(_M_mutex);
00238 if (!_M_ready())
00239 _M_cond.wait(__lock, std::bind(&_State::_M_ready, this));
00240 return *_M_result;
00241 }
00242
00243 template<typename _Rep, typename _Period>
00244 bool
00245 wait_for(const chrono::duration<_Rep, _Period>& __rel)
00246 {
00247 unique_lock<mutex> __lock(_M_mutex);
00248 auto __bound = std::bind(&_State::_M_ready, this);
00249 return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound);
00250 }
00251
00252 template<typename _Clock, typename _Duration>
00253 bool
00254 wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
00255 {
00256 unique_lock<mutex> __lock(_M_mutex);
00257 auto __bound = std::bind(&_State::_M_ready, this);
00258 return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound);
00259 }
00260
00261 void
00262 _M_set_result(_Ptr_type __res)
00263 {
00264 {
00265 lock_guard<mutex> __lock(_M_mutex);
00266 if (_M_ready())
00267 __throw_future_error(int(future_errc::promise_already_satisfied));
00268 _M_result.swap(__res);
00269 }
00270 _M_cond.notify_all();
00271 }
00272
00273 void
00274 _M_break_promise(_Ptr_type __res)
00275 {
00276 if (static_cast<bool>(__res))
00277 {
00278 future_errc __ec(future_errc::broken_promise);
00279 __res->_M_error = copy_exception(future_error(__ec));
00280 {
00281 lock_guard<mutex> __lock(_M_mutex);
00282 _M_result.swap(__res);
00283 }
00284 _M_cond.notify_all();
00285 }
00286 }
00287
00288
00289 void
00290 _M_set_retrieved_flag()
00291 {
00292 if (_M_retrieved.test_and_set())
00293 __throw_future_error(int(future_errc::future_already_retrieved));
00294 }
00295
00296 private:
00297 _Result_base*
00298 _M_get()
00299 {
00300 lock_guard<mutex> __lock(_M_mutex);
00301 return _M_result.get();
00302 }
00303
00304 bool _M_ready() const { return static_cast<bool>(_M_result); }
00305 };
00306 };
00307
00308 inline __future_base::_Result_base::~_Result_base() = default;
00309
00310
00311 template<typename _Res>
00312 struct __future_base::_Result<_Res&> : __future_base::_Result_base
00313 {
00314 _Result() : _M_value_ptr() { }
00315
00316 _Res* _M_value_ptr;
00317
00318 private:
00319 void _M_destroy() { delete this; }
00320 };
00321
00322
00323 template<>
00324 struct __future_base::_Result<void> : __future_base::_Result_base
00325 {
00326 private:
00327 void _M_destroy() { delete this; }
00328 };
00329
00330
00331
00332 template<typename _Res>
00333 class __basic_future : public __future_base
00334 {
00335 protected:
00336 typedef shared_ptr<_State> __state_type;
00337 typedef __future_base::_Result<_Res>& __result_type;
00338
00339 private:
00340 __state_type _M_state;
00341
00342 public:
00343
00344 __basic_future(const __basic_future&) = delete;
00345 __basic_future& operator=(const __basic_future&) = delete;
00346
00347
00348 bool
00349 is_ready() const { return this->_M_state->is_ready(); }
00350
00351 bool
00352 has_exception() const { return this->_M_state->has_exception(); }
00353
00354 bool
00355 has_value() const { return this->_M_state->has_value(); }
00356
00357 void
00358 wait() const { this->_M_state->wait(); }
00359
00360 template<typename _Rep, typename _Period>
00361 bool
00362 wait_for(const chrono::duration<_Rep, _Period>& __rel) const
00363 { return this->_M_state->wait_for(__rel); }
00364
00365 template<typename _Clock, typename _Duration>
00366 bool
00367 wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
00368 { return this->_M_state->wait_until(__abs); }
00369
00370 protected:
00371
00372 __result_type
00373 _M_get_result()
00374 {
00375 _Result_base& __res = this->_M_state->wait();
00376 if (!(__res._M_error == 0))
00377 rethrow_exception(__res._M_error);
00378 return static_cast<__result_type>(__res);
00379 }
00380
00381
00382 explicit
00383 __basic_future(const __state_type& __state) : _M_state(__state)
00384 {
00385 if (static_cast<bool>(this->_M_state))
00386 this->_M_state->_M_set_retrieved_flag();
00387 else
00388 __throw_future_error(int(future_errc::future_already_retrieved));
00389 }
00390
00391
00392 explicit
00393 __basic_future(const shared_future<_Res>&);
00394
00395
00396 explicit
00397 __basic_future(unique_future<_Res>&&);
00398 };
00399
00400
00401
00402 template<typename _Res>
00403 class unique_future : public __basic_future<_Res>
00404 {
00405 friend class promise<_Res>;
00406
00407 typedef __basic_future<_Res> _Base_type;
00408 typedef typename _Base_type::__state_type __state_type;
00409
00410 explicit
00411 unique_future(const __state_type& __state) : _Base_type(__state) { }
00412
00413 public:
00414
00415 unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
00416
00417
00418 unique_future(const unique_future&) = delete;
00419 unique_future& operator=(const unique_future&) = delete;
00420
00421
00422 _Res&&
00423 get()
00424 { return std::move(this->_M_get_result()._M_value()); }
00425 };
00426
00427
00428 template<typename _Res>
00429 class unique_future<_Res&> : public __basic_future<_Res&>
00430 {
00431 friend class promise<_Res&>;
00432
00433 typedef __basic_future<_Res&> _Base_type;
00434 typedef typename _Base_type::__state_type __state_type;
00435
00436 explicit
00437 unique_future(const __state_type& __state) : _Base_type(__state) { }
00438
00439 public:
00440
00441 unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
00442
00443
00444 unique_future(const unique_future&) = delete;
00445 unique_future& operator=(const unique_future&) = delete;
00446
00447
00448 _Res&
00449 get() { return *this->_M_get_result()._M_value_ptr; }
00450 };
00451
00452
00453 template<>
00454 class unique_future<void> : public __basic_future<void>
00455 {
00456 friend class promise<void>;
00457
00458 typedef __basic_future<void> _Base_type;
00459 typedef typename _Base_type::__state_type __state_type;
00460
00461 explicit
00462 unique_future(const __state_type& __state) : _Base_type(__state) { }
00463
00464 public:
00465
00466 unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { }
00467
00468
00469 unique_future(const unique_future&) = delete;
00470 unique_future& operator=(const unique_future&) = delete;
00471
00472
00473 void
00474 get() { this->_M_get_result(); }
00475 };
00476
00477
00478
00479 template<typename _Res>
00480 class shared_future : public __basic_future<_Res>
00481 {
00482 typedef __basic_future<_Res> _Base_type;
00483
00484 public:
00485
00486 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
00487
00488
00489 shared_future(unique_future<_Res>&& __uf)
00490 : _Base_type(std::move(__uf))
00491 { }
00492
00493 shared_future& operator=(const shared_future&) = delete;
00494
00495
00496 const _Res&
00497 get()
00498 {
00499 typename _Base_type::__result_type __r = this->_M_get_result();
00500 _Res& __rs(__r._M_value());
00501 return __rs;
00502 }
00503 };
00504
00505
00506 template<typename _Res>
00507 class shared_future<_Res&> : public __basic_future<_Res&>
00508 {
00509 typedef __basic_future<_Res&> _Base_type;
00510
00511 public:
00512
00513 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
00514
00515
00516 shared_future(unique_future<_Res&>&& __uf)
00517 : _Base_type(std::move(__uf))
00518 { }
00519
00520 shared_future& operator=(const shared_future&) = delete;
00521
00522
00523 _Res&
00524 get() { return *this->_M_get_result()._M_value_ptr; }
00525 };
00526
00527
00528 template<>
00529 class shared_future<void> : public __basic_future<void>
00530 {
00531 typedef __basic_future<void> _Base_type;
00532
00533 public:
00534
00535 shared_future(const shared_future& __sf) : _Base_type(__sf) { }
00536
00537
00538 shared_future(unique_future<void>&& __uf)
00539 : _Base_type(std::move(__uf))
00540 { }
00541
00542 shared_future& operator=(const shared_future&) = delete;
00543
00544
00545 void
00546 get() { this->_M_get_result(); }
00547 };
00548
00549
00550 template<typename _Res>
00551 __basic_future<_Res>::__basic_future(const shared_future<_Res>& __sf)
00552 : _M_state(__sf._M_state)
00553 { }
00554
00555 template<typename _Res>
00556 __basic_future<_Res>::__basic_future(unique_future<_Res>&& __uf)
00557 : _M_state(std::move(__uf._M_state))
00558 { }
00559
00560
00561
00562 template<typename _Res>
00563 class promise
00564 {
00565 template<typename> friend class packaged_task;
00566
00567 typedef __future_base::_State _State;
00568 typedef __future_base::_Result<_Res> result_type;
00569
00570 shared_ptr<_State> _M_future;
00571 typename __future_base::_Ptr<result_type>::type _M_storage;
00572
00573 public:
00574 promise()
00575 : _M_future(std::make_shared<_State>()), _M_storage(new result_type())
00576 { }
00577
00578 promise(promise&& __rhs)
00579 : _M_future(std::move(__rhs._M_future)),
00580 _M_storage(std::move(__rhs._M_storage))
00581 { }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 promise(const promise&) = delete;
00593
00594 ~promise()
00595 {
00596 if (static_cast<bool>(_M_future) && !_M_future.unique())
00597 _M_future->_M_break_promise(std::move(_M_storage));
00598 }
00599
00600
00601 promise&
00602 operator=(promise&& __rhs)
00603 {
00604 promise(std::move(__rhs)).swap(*this);
00605 return *this;
00606 }
00607
00608 promise& operator=(const promise&) = delete;
00609
00610 void
00611 swap(promise& __rhs)
00612 {
00613 _M_future.swap(__rhs._M_future);
00614 _M_storage.swap(__rhs._M_storage);
00615 }
00616
00617
00618 unique_future<_Res>
00619 get_future()
00620 { return unique_future<_Res>(_M_future); }
00621
00622
00623 void
00624 set_value(const _Res& __r)
00625 {
00626 if (!_M_satisfied())
00627 _M_storage->_M_set(__r);
00628 _M_future->_M_set_result(std::move(_M_storage));
00629 }
00630
00631 void
00632 set_value(_Res&& __r)
00633 {
00634 if (!_M_satisfied())
00635 _M_storage->_M_set(std::move(__r));
00636 _M_future->_M_set_result(std::move(_M_storage));
00637 }
00638
00639 void
00640 set_exception(exception_ptr __p)
00641 {
00642 if (!_M_satisfied())
00643 _M_storage->_M_error = __p;
00644 _M_future->_M_set_result(std::move(_M_storage));
00645 }
00646
00647 private:
00648 bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
00649 };
00650
00651
00652 template<typename _Res>
00653 class promise<_Res&>
00654 {
00655 template<typename> friend class packaged_task;
00656 typedef __future_base::_State _State;
00657
00658 typedef __future_base::_Result<_Res&> result_type;
00659
00660 shared_ptr<_State> _M_future;
00661 typename __future_base::_Ptr<result_type>::type _M_storage;
00662
00663 public:
00664 promise()
00665 : _M_future(std::make_shared<_State>()), _M_storage(new result_type())
00666 { }
00667
00668 promise(promise&& __rhs)
00669 : _M_future(std::move(__rhs._M_future)),
00670 _M_storage(std::move(__rhs._M_storage))
00671 { }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 promise(const promise&) = delete;
00683
00684 ~promise()
00685 {
00686 if (static_cast<bool>(_M_future) && !_M_future.unique())
00687 _M_future->_M_break_promise(std::move(_M_storage));
00688 }
00689
00690
00691 promise&
00692 operator=(promise&& __rhs)
00693 {
00694 promise(std::move(__rhs)).swap(*this);
00695 return *this;
00696 }
00697
00698 promise& operator=(const promise&) = delete;
00699
00700 void
00701 swap(promise& __rhs)
00702 {
00703 _M_future.swap(__rhs._M_future);
00704 _M_storage.swap(__rhs._M_storage);
00705 }
00706
00707
00708 unique_future<_Res&>
00709 get_future()
00710 { return unique_future<_Res&>(_M_future); }
00711
00712
00713 void
00714 set_value(_Res& __r)
00715 {
00716 if (!_M_satisfied())
00717 _M_storage->_M_value_ptr = &__r;
00718 _M_future->_M_set_result(std::move(_M_storage));
00719 }
00720
00721 void
00722 set_exception(exception_ptr __p)
00723 {
00724 if (!_M_satisfied())
00725 _M_storage->_M_error = __p;
00726 _M_future->_M_set_result(std::move(_M_storage));
00727 }
00728
00729 private:
00730 bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
00731 };
00732
00733
00734 template<>
00735 class promise<void>
00736 {
00737 template<typename> friend class packaged_task;
00738 typedef __future_base::_State _State;
00739 typedef __future_base::_Result<void> result_type;
00740
00741 shared_ptr<__future_base::_State> _M_future;
00742 typename __future_base::_Ptr<result_type>::type _M_storage;
00743
00744 public:
00745 promise()
00746 : _M_future(std::make_shared<_State>()),
00747 _M_storage(new result_type())
00748 { }
00749
00750 promise(promise&& __rhs)
00751 : _M_future(std::move(__rhs._M_future)),
00752 _M_storage(std::move(__rhs._M_storage))
00753 { }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 promise(const promise&) = delete;
00765
00766 ~promise()
00767 {
00768 if (static_cast<bool>(_M_future) && !_M_future.unique())
00769 _M_future->_M_break_promise(std::move(_M_storage));
00770 }
00771
00772
00773 promise&
00774 operator=(promise&& __rhs)
00775 {
00776 promise(std::move(__rhs)).swap(*this);
00777 return *this;
00778 }
00779
00780 promise& operator=(const promise&) = delete;
00781
00782 void
00783 swap(promise& __rhs)
00784 {
00785 _M_future.swap(__rhs._M_future);
00786 _M_storage.swap(__rhs._M_storage);
00787 }
00788
00789
00790 unique_future<void>
00791 get_future()
00792 { return unique_future<void>(_M_future); }
00793
00794
00795 void
00796 set_value()
00797 {
00798 _M_future->_M_set_result(std::move(_M_storage));
00799 }
00800
00801 void
00802 set_exception(exception_ptr __p)
00803 {
00804 if (!_M_satisfied())
00805 _M_storage->_M_error = __p;
00806 _M_future->_M_set_result(std::move(_M_storage));
00807 }
00808
00809 private:
00810 bool _M_satisfied() { return !static_cast<bool>(_M_storage); }
00811 };
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 template<typename _Res, typename... _ArgTypes>
00823 struct _Run_task
00824 {
00825 static void
00826 _S_run(promise<_Res>& __p, function<_Res(_ArgTypes...)>& __f,
00827 _ArgTypes... __args)
00828 {
00829 __p.set_value(__f(std::forward<_ArgTypes>(__args)...));
00830 }
00831 };
00832
00833
00834 template<typename... _ArgTypes>
00835 struct _Run_task<void, _ArgTypes...>
00836 {
00837 static void
00838 _S_run(promise<void>& __p, function<void(_ArgTypes...)>& __f,
00839 _ArgTypes... __args)
00840 {
00841 __f(std::forward<_ArgTypes>(__args)...);
00842 __p.set_value();
00843 }
00844 };
00845
00846
00847
00848 template<typename _Res, typename... _ArgTypes>
00849 class packaged_task<_Res(_ArgTypes...)>
00850 {
00851 function<_Res(_ArgTypes...)> _M_task;
00852 promise<_Res> _M_promise;
00853
00854 public:
00855 typedef _Res result_type;
00856
00857
00858 packaged_task() { }
00859
00860 template<typename _Fn>
00861 explicit
00862 packaged_task(const _Fn& __fn) : _M_task(__fn) { }
00863
00864 template<typename _Fn>
00865 explicit
00866 packaged_task(_Fn&& __fn) : _M_task(std::move(__fn)) { }
00867
00868 explicit
00869 packaged_task(_Res(*__fn)(_ArgTypes...)) : _M_task(__fn) { }
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 ~packaged_task() = default;
00887
00888
00889 packaged_task(packaged_task&) = delete;
00890 packaged_task& operator=(packaged_task&) = delete;
00891
00892
00893 packaged_task(packaged_task&& __other)
00894 { this->swap(__other); }
00895
00896 packaged_task& operator=(packaged_task&& __other)
00897 {
00898 packaged_task(std::move(__other)).swap(*this);
00899 return *this;
00900 }
00901
00902 void
00903 swap(packaged_task& __other)
00904 {
00905 _M_task.swap(__other._M_task);
00906 _M_promise.swap(__other._M_promise);
00907 }
00908
00909 explicit operator bool() const { return static_cast<bool>(_M_task); }
00910
00911
00912 unique_future<_Res>
00913 get_future()
00914 {
00915 __try
00916 {
00917 return _M_promise.get_future();
00918 }
00919 __catch (const future_error& __e)
00920 {
00921 if (__e.code() == future_errc::future_already_retrieved)
00922 __throw_bad_function_call();
00923 __throw_exception_again;
00924 }
00925 }
00926
00927
00928 void
00929 operator()(_ArgTypes... __args)
00930 {
00931 if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied())
00932 __throw_bad_function_call();
00933
00934 __try
00935 {
00936 _Run_task<_Res, _ArgTypes...>::_S_run(_M_promise, _M_task,
00937 std::forward<_ArgTypes>(__args)...);
00938 }
00939 __catch (...)
00940 {
00941 _M_promise.set_exception(current_exception());
00942 }
00943 }
00944
00945 void reset() { promise<_Res>().swap(_M_promise); }
00946 };
00947
00948 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
00949
00950
00951
00952 }
00953
00954 #endif // __GXX_EXPERIMENTAL_CXX0X__
00955
00956 #endif // _GLIBCXX_FUTURE