1*4684ddb6SLionel Sambuc //===------------------------- future.cpp ---------------------------------===// 2*4684ddb6SLionel Sambuc // 3*4684ddb6SLionel Sambuc // The LLVM Compiler Infrastructure 4*4684ddb6SLionel Sambuc // 5*4684ddb6SLionel Sambuc // This file is dual licensed under the MIT and the University of Illinois Open 6*4684ddb6SLionel Sambuc // Source Licenses. See LICENSE.TXT for details. 7*4684ddb6SLionel Sambuc // 8*4684ddb6SLionel Sambuc //===----------------------------------------------------------------------===// 9*4684ddb6SLionel Sambuc 10*4684ddb6SLionel Sambuc #include "future" 11*4684ddb6SLionel Sambuc #include "string" 12*4684ddb6SLionel Sambuc 13*4684ddb6SLionel Sambuc _LIBCPP_BEGIN_NAMESPACE_STD 14*4684ddb6SLionel Sambuc 15*4684ddb6SLionel Sambuc class _LIBCPP_HIDDEN __future_error_category 16*4684ddb6SLionel Sambuc : public __do_message 17*4684ddb6SLionel Sambuc { 18*4684ddb6SLionel Sambuc public: 19*4684ddb6SLionel Sambuc virtual const char* name() const _NOEXCEPT; 20*4684ddb6SLionel Sambuc virtual string message(int ev) const; 21*4684ddb6SLionel Sambuc }; 22*4684ddb6SLionel Sambuc 23*4684ddb6SLionel Sambuc const char* 24*4684ddb6SLionel Sambuc __future_error_category::name() const _NOEXCEPT 25*4684ddb6SLionel Sambuc { 26*4684ddb6SLionel Sambuc return "future"; 27*4684ddb6SLionel Sambuc } 28*4684ddb6SLionel Sambuc 29*4684ddb6SLionel Sambuc #pragma clang diagnostic push 30*4684ddb6SLionel Sambuc #pragma clang diagnostic ignored "-Wswitch" 31*4684ddb6SLionel Sambuc 32*4684ddb6SLionel Sambuc string 33*4684ddb6SLionel Sambuc __future_error_category::message(int ev) const 34*4684ddb6SLionel Sambuc { 35*4684ddb6SLionel Sambuc switch (static_cast<future_errc>(ev)) 36*4684ddb6SLionel Sambuc { 37*4684ddb6SLionel Sambuc case future_errc(0): // For backwards compatibility with C++11 (LWG 2056) 38*4684ddb6SLionel Sambuc case future_errc::broken_promise: 39*4684ddb6SLionel Sambuc return string("The associated promise has been destructed prior " 40*4684ddb6SLionel Sambuc "to the associated state becoming ready."); 41*4684ddb6SLionel Sambuc case future_errc::future_already_retrieved: 42*4684ddb6SLionel Sambuc return string("The future has already been retrieved from " 43*4684ddb6SLionel Sambuc "the promise or packaged_task."); 44*4684ddb6SLionel Sambuc case future_errc::promise_already_satisfied: 45*4684ddb6SLionel Sambuc return string("The state of the promise has already been set."); 46*4684ddb6SLionel Sambuc case future_errc::no_state: 47*4684ddb6SLionel Sambuc return string("Operation not permitted on an object without " 48*4684ddb6SLionel Sambuc "an associated state."); 49*4684ddb6SLionel Sambuc } 50*4684ddb6SLionel Sambuc return string("unspecified future_errc value\n"); 51*4684ddb6SLionel Sambuc } 52*4684ddb6SLionel Sambuc 53*4684ddb6SLionel Sambuc #pragma clang diagnostic pop 54*4684ddb6SLionel Sambuc 55*4684ddb6SLionel Sambuc const error_category& 56*4684ddb6SLionel Sambuc future_category() _NOEXCEPT 57*4684ddb6SLionel Sambuc { 58*4684ddb6SLionel Sambuc static __future_error_category __f; 59*4684ddb6SLionel Sambuc return __f; 60*4684ddb6SLionel Sambuc } 61*4684ddb6SLionel Sambuc 62*4684ddb6SLionel Sambuc future_error::future_error(error_code __ec) 63*4684ddb6SLionel Sambuc : logic_error(__ec.message()), 64*4684ddb6SLionel Sambuc __ec_(__ec) 65*4684ddb6SLionel Sambuc { 66*4684ddb6SLionel Sambuc } 67*4684ddb6SLionel Sambuc 68*4684ddb6SLionel Sambuc future_error::~future_error() _NOEXCEPT 69*4684ddb6SLionel Sambuc { 70*4684ddb6SLionel Sambuc } 71*4684ddb6SLionel Sambuc 72*4684ddb6SLionel Sambuc void 73*4684ddb6SLionel Sambuc __assoc_sub_state::__on_zero_shared() _NOEXCEPT 74*4684ddb6SLionel Sambuc { 75*4684ddb6SLionel Sambuc delete this; 76*4684ddb6SLionel Sambuc } 77*4684ddb6SLionel Sambuc 78*4684ddb6SLionel Sambuc void 79*4684ddb6SLionel Sambuc __assoc_sub_state::set_value() 80*4684ddb6SLionel Sambuc { 81*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 82*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 83*4684ddb6SLionel Sambuc if (__has_value()) 84*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::promise_already_satisfied)); 85*4684ddb6SLionel Sambuc #endif 86*4684ddb6SLionel Sambuc __state_ |= __constructed | ready; 87*4684ddb6SLionel Sambuc __cv_.notify_all(); 88*4684ddb6SLionel Sambuc __lk.unlock(); 89*4684ddb6SLionel Sambuc } 90*4684ddb6SLionel Sambuc 91*4684ddb6SLionel Sambuc void 92*4684ddb6SLionel Sambuc __assoc_sub_state::set_value_at_thread_exit() 93*4684ddb6SLionel Sambuc { 94*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 95*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 96*4684ddb6SLionel Sambuc if (__has_value()) 97*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::promise_already_satisfied)); 98*4684ddb6SLionel Sambuc #endif 99*4684ddb6SLionel Sambuc __state_ |= __constructed; 100*4684ddb6SLionel Sambuc __thread_local_data()->__make_ready_at_thread_exit(this); 101*4684ddb6SLionel Sambuc __lk.unlock(); 102*4684ddb6SLionel Sambuc } 103*4684ddb6SLionel Sambuc 104*4684ddb6SLionel Sambuc void 105*4684ddb6SLionel Sambuc __assoc_sub_state::set_exception(exception_ptr __p) 106*4684ddb6SLionel Sambuc { 107*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 108*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 109*4684ddb6SLionel Sambuc if (__has_value()) 110*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::promise_already_satisfied)); 111*4684ddb6SLionel Sambuc #endif 112*4684ddb6SLionel Sambuc __exception_ = __p; 113*4684ddb6SLionel Sambuc __state_ |= ready; 114*4684ddb6SLionel Sambuc __lk.unlock(); 115*4684ddb6SLionel Sambuc __cv_.notify_all(); 116*4684ddb6SLionel Sambuc } 117*4684ddb6SLionel Sambuc 118*4684ddb6SLionel Sambuc void 119*4684ddb6SLionel Sambuc __assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p) 120*4684ddb6SLionel Sambuc { 121*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 122*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 123*4684ddb6SLionel Sambuc if (__has_value()) 124*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::promise_already_satisfied)); 125*4684ddb6SLionel Sambuc #endif 126*4684ddb6SLionel Sambuc __exception_ = __p; 127*4684ddb6SLionel Sambuc __thread_local_data()->__make_ready_at_thread_exit(this); 128*4684ddb6SLionel Sambuc __lk.unlock(); 129*4684ddb6SLionel Sambuc } 130*4684ddb6SLionel Sambuc 131*4684ddb6SLionel Sambuc void 132*4684ddb6SLionel Sambuc __assoc_sub_state::__make_ready() 133*4684ddb6SLionel Sambuc { 134*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 135*4684ddb6SLionel Sambuc __state_ |= ready; 136*4684ddb6SLionel Sambuc __lk.unlock(); 137*4684ddb6SLionel Sambuc __cv_.notify_all(); 138*4684ddb6SLionel Sambuc } 139*4684ddb6SLionel Sambuc 140*4684ddb6SLionel Sambuc void 141*4684ddb6SLionel Sambuc __assoc_sub_state::copy() 142*4684ddb6SLionel Sambuc { 143*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 144*4684ddb6SLionel Sambuc __sub_wait(__lk); 145*4684ddb6SLionel Sambuc if (__exception_ != nullptr) 146*4684ddb6SLionel Sambuc rethrow_exception(__exception_); 147*4684ddb6SLionel Sambuc } 148*4684ddb6SLionel Sambuc 149*4684ddb6SLionel Sambuc void 150*4684ddb6SLionel Sambuc __assoc_sub_state::wait() 151*4684ddb6SLionel Sambuc { 152*4684ddb6SLionel Sambuc unique_lock<mutex> __lk(__mut_); 153*4684ddb6SLionel Sambuc __sub_wait(__lk); 154*4684ddb6SLionel Sambuc } 155*4684ddb6SLionel Sambuc 156*4684ddb6SLionel Sambuc void 157*4684ddb6SLionel Sambuc __assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk) 158*4684ddb6SLionel Sambuc { 159*4684ddb6SLionel Sambuc if (!__is_ready()) 160*4684ddb6SLionel Sambuc { 161*4684ddb6SLionel Sambuc if (__state_ & static_cast<unsigned>(deferred)) 162*4684ddb6SLionel Sambuc { 163*4684ddb6SLionel Sambuc __state_ &= ~static_cast<unsigned>(deferred); 164*4684ddb6SLionel Sambuc __lk.unlock(); 165*4684ddb6SLionel Sambuc __execute(); 166*4684ddb6SLionel Sambuc } 167*4684ddb6SLionel Sambuc else 168*4684ddb6SLionel Sambuc while (!__is_ready()) 169*4684ddb6SLionel Sambuc __cv_.wait(__lk); 170*4684ddb6SLionel Sambuc } 171*4684ddb6SLionel Sambuc } 172*4684ddb6SLionel Sambuc 173*4684ddb6SLionel Sambuc void 174*4684ddb6SLionel Sambuc __assoc_sub_state::__execute() 175*4684ddb6SLionel Sambuc { 176*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 177*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::no_state)); 178*4684ddb6SLionel Sambuc #endif 179*4684ddb6SLionel Sambuc } 180*4684ddb6SLionel Sambuc 181*4684ddb6SLionel Sambuc future<void>::future(__assoc_sub_state* __state) 182*4684ddb6SLionel Sambuc : __state_(__state) 183*4684ddb6SLionel Sambuc { 184*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 185*4684ddb6SLionel Sambuc if (__state_->__has_future_attached()) 186*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::future_already_retrieved)); 187*4684ddb6SLionel Sambuc #endif 188*4684ddb6SLionel Sambuc __state_->__add_shared(); 189*4684ddb6SLionel Sambuc __state_->__set_future_attached(); 190*4684ddb6SLionel Sambuc } 191*4684ddb6SLionel Sambuc 192*4684ddb6SLionel Sambuc future<void>::~future() 193*4684ddb6SLionel Sambuc { 194*4684ddb6SLionel Sambuc if (__state_) 195*4684ddb6SLionel Sambuc __state_->__release_shared(); 196*4684ddb6SLionel Sambuc } 197*4684ddb6SLionel Sambuc 198*4684ddb6SLionel Sambuc void 199*4684ddb6SLionel Sambuc future<void>::get() 200*4684ddb6SLionel Sambuc { 201*4684ddb6SLionel Sambuc unique_ptr<__shared_count, __release_shared_count> __(__state_); 202*4684ddb6SLionel Sambuc __assoc_sub_state* __s = __state_; 203*4684ddb6SLionel Sambuc __state_ = nullptr; 204*4684ddb6SLionel Sambuc __s->copy(); 205*4684ddb6SLionel Sambuc } 206*4684ddb6SLionel Sambuc 207*4684ddb6SLionel Sambuc promise<void>::promise() 208*4684ddb6SLionel Sambuc : __state_(new __assoc_sub_state) 209*4684ddb6SLionel Sambuc { 210*4684ddb6SLionel Sambuc } 211*4684ddb6SLionel Sambuc 212*4684ddb6SLionel Sambuc promise<void>::~promise() 213*4684ddb6SLionel Sambuc { 214*4684ddb6SLionel Sambuc if (__state_) 215*4684ddb6SLionel Sambuc { 216*4684ddb6SLionel Sambuc if (!__state_->__has_value() && __state_->use_count() > 1) 217*4684ddb6SLionel Sambuc __state_->set_exception(make_exception_ptr( 218*4684ddb6SLionel Sambuc future_error(make_error_code(future_errc::broken_promise)) 219*4684ddb6SLionel Sambuc )); 220*4684ddb6SLionel Sambuc __state_->__release_shared(); 221*4684ddb6SLionel Sambuc } 222*4684ddb6SLionel Sambuc } 223*4684ddb6SLionel Sambuc 224*4684ddb6SLionel Sambuc future<void> 225*4684ddb6SLionel Sambuc promise<void>::get_future() 226*4684ddb6SLionel Sambuc { 227*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 228*4684ddb6SLionel Sambuc if (__state_ == nullptr) 229*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::no_state)); 230*4684ddb6SLionel Sambuc #endif 231*4684ddb6SLionel Sambuc return future<void>(__state_); 232*4684ddb6SLionel Sambuc } 233*4684ddb6SLionel Sambuc 234*4684ddb6SLionel Sambuc void 235*4684ddb6SLionel Sambuc promise<void>::set_value() 236*4684ddb6SLionel Sambuc { 237*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 238*4684ddb6SLionel Sambuc if (__state_ == nullptr) 239*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::no_state)); 240*4684ddb6SLionel Sambuc #endif 241*4684ddb6SLionel Sambuc __state_->set_value(); 242*4684ddb6SLionel Sambuc } 243*4684ddb6SLionel Sambuc 244*4684ddb6SLionel Sambuc void 245*4684ddb6SLionel Sambuc promise<void>::set_exception(exception_ptr __p) 246*4684ddb6SLionel Sambuc { 247*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 248*4684ddb6SLionel Sambuc if (__state_ == nullptr) 249*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::no_state)); 250*4684ddb6SLionel Sambuc #endif 251*4684ddb6SLionel Sambuc __state_->set_exception(__p); 252*4684ddb6SLionel Sambuc } 253*4684ddb6SLionel Sambuc 254*4684ddb6SLionel Sambuc void 255*4684ddb6SLionel Sambuc promise<void>::set_value_at_thread_exit() 256*4684ddb6SLionel Sambuc { 257*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 258*4684ddb6SLionel Sambuc if (__state_ == nullptr) 259*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::no_state)); 260*4684ddb6SLionel Sambuc #endif 261*4684ddb6SLionel Sambuc __state_->set_value_at_thread_exit(); 262*4684ddb6SLionel Sambuc } 263*4684ddb6SLionel Sambuc 264*4684ddb6SLionel Sambuc void 265*4684ddb6SLionel Sambuc promise<void>::set_exception_at_thread_exit(exception_ptr __p) 266*4684ddb6SLionel Sambuc { 267*4684ddb6SLionel Sambuc #ifndef _LIBCPP_NO_EXCEPTIONS 268*4684ddb6SLionel Sambuc if (__state_ == nullptr) 269*4684ddb6SLionel Sambuc throw future_error(make_error_code(future_errc::no_state)); 270*4684ddb6SLionel Sambuc #endif 271*4684ddb6SLionel Sambuc __state_->set_exception_at_thread_exit(__p); 272*4684ddb6SLionel Sambuc } 273*4684ddb6SLionel Sambuc 274*4684ddb6SLionel Sambuc shared_future<void>::~shared_future() 275*4684ddb6SLionel Sambuc { 276*4684ddb6SLionel Sambuc if (__state_) 277*4684ddb6SLionel Sambuc __state_->__release_shared(); 278*4684ddb6SLionel Sambuc } 279*4684ddb6SLionel Sambuc 280*4684ddb6SLionel Sambuc shared_future<void>& 281*4684ddb6SLionel Sambuc shared_future<void>::operator=(const shared_future& __rhs) 282*4684ddb6SLionel Sambuc { 283*4684ddb6SLionel Sambuc if (__rhs.__state_) 284*4684ddb6SLionel Sambuc __rhs.__state_->__add_shared(); 285*4684ddb6SLionel Sambuc if (__state_) 286*4684ddb6SLionel Sambuc __state_->__release_shared(); 287*4684ddb6SLionel Sambuc __state_ = __rhs.__state_; 288*4684ddb6SLionel Sambuc return *this; 289*4684ddb6SLionel Sambuc } 290*4684ddb6SLionel Sambuc 291*4684ddb6SLionel Sambuc _LIBCPP_END_NAMESPACE_STD 292