1eb8650a7SLouis Dionne //===----------------------------------------------------------------------===// 2dae3481bSHoward Hinnant // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6dae3481bSHoward Hinnant // 7dae3481bSHoward Hinnant //===----------------------------------------------------------------------===// 8dae3481bSHoward Hinnant 9*bbb0f2c7SArthur O'Dwyer #include <__config> 10b3fcc67fSJonathan Roelofs 11b3fcc67fSJonathan Roelofs #ifndef _LIBCPP_HAS_NO_THREADS 12b3fcc67fSJonathan Roelofs 13*bbb0f2c7SArthur O'Dwyer #include <future> 14*bbb0f2c7SArthur O'Dwyer #include <string> 15dae3481bSHoward Hinnant 16dae3481bSHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD 17dae3481bSHoward Hinnant 18dae3481bSHoward Hinnant class _LIBCPP_HIDDEN __future_error_category 19dae3481bSHoward Hinnant : public __do_message 20dae3481bSHoward Hinnant { 21dae3481bSHoward Hinnant public: 225601305fSLouis Dionne virtual const char* name() const noexcept; 23dae3481bSHoward Hinnant virtual string message(int ev) const; 24dae3481bSHoward Hinnant }; 25dae3481bSHoward Hinnant 26dae3481bSHoward Hinnant const char* name() const275601305fSLouis Dionne__future_error_category::name() const noexcept 28dae3481bSHoward Hinnant { 29dae3481bSHoward Hinnant return "future"; 30dae3481bSHoward Hinnant } 31dae3481bSHoward Hinnant 32a7c2a628SNikolas Klauser _LIBCPP_DIAGNOSTIC_PUSH 33a7c2a628SNikolas Klauser _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wswitch") 34a7c2a628SNikolas Klauser _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wswitch") 353b2d7ee1SHoward Hinnant 36dae3481bSHoward Hinnant string message(int ev) const37dae3481bSHoward Hinnant__future_error_category::message(int ev) const 38dae3481bSHoward Hinnant { 39be745c8cSHoward Hinnant switch (static_cast<future_errc>(ev)) 40dae3481bSHoward Hinnant { 413b2d7ee1SHoward Hinnant case future_errc(0): // For backwards compatibility with C++11 (LWG 2056) 42dae3481bSHoward Hinnant case future_errc::broken_promise: 43dae3481bSHoward Hinnant return string("The associated promise has been destructed prior " 44dae3481bSHoward Hinnant "to the associated state becoming ready."); 45dae3481bSHoward Hinnant case future_errc::future_already_retrieved: 46dae3481bSHoward Hinnant return string("The future has already been retrieved from " 47dae3481bSHoward Hinnant "the promise or packaged_task."); 48dae3481bSHoward Hinnant case future_errc::promise_already_satisfied: 49dae3481bSHoward Hinnant return string("The state of the promise has already been set."); 50dae3481bSHoward Hinnant case future_errc::no_state: 51dae3481bSHoward Hinnant return string("Operation not permitted on an object without " 52dae3481bSHoward Hinnant "an associated state."); 53dae3481bSHoward Hinnant } 54dae3481bSHoward Hinnant return string("unspecified future_errc value\n"); 55dae3481bSHoward Hinnant } 56dae3481bSHoward Hinnant 57a7c2a628SNikolas Klauser _LIBCPP_DIAGNOSTIC_POP 583b2d7ee1SHoward Hinnant 59dae3481bSHoward Hinnant const error_category& future_category()605601305fSLouis Dionnefuture_category() noexcept 61dae3481bSHoward Hinnant { 62dae3481bSHoward Hinnant static __future_error_category __f; 63dae3481bSHoward Hinnant return __f; 64dae3481bSHoward Hinnant } 65dae3481bSHoward Hinnant future_error(error_code __ec)66dae3481bSHoward Hinnantfuture_error::future_error(error_code __ec) 67dae3481bSHoward Hinnant : logic_error(__ec.message()), 68dae3481bSHoward Hinnant __ec_(__ec) 69dae3481bSHoward Hinnant { 70dae3481bSHoward Hinnant } 71dae3481bSHoward Hinnant ~future_error()725601305fSLouis Dionnefuture_error::~future_error() noexcept 733aa229f7SHoward Hinnant { 743aa229f7SHoward Hinnant } 753aa229f7SHoward Hinnant 76167fd108SHoward Hinnant void __on_zero_shared()775601305fSLouis Dionne__assoc_sub_state::__on_zero_shared() noexcept 78167fd108SHoward Hinnant { 79167fd108SHoward Hinnant delete this; 80167fd108SHoward Hinnant } 81167fd108SHoward Hinnant 82167fd108SHoward Hinnant void set_value()83167fd108SHoward Hinnant__assoc_sub_state::set_value() 84167fd108SHoward Hinnant { 85167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 86167fd108SHoward Hinnant if (__has_value()) 87934864bfSMarshall Clow __throw_future_error(future_errc::promise_already_satisfied); 88167fd108SHoward Hinnant __state_ |= __constructed | ready; 89167fd108SHoward Hinnant __cv_.notify_all(); 90167fd108SHoward Hinnant } 91167fd108SHoward Hinnant 92167fd108SHoward Hinnant void set_value_at_thread_exit()93167fd108SHoward Hinnant__assoc_sub_state::set_value_at_thread_exit() 94167fd108SHoward Hinnant { 95167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 96167fd108SHoward Hinnant if (__has_value()) 97934864bfSMarshall Clow __throw_future_error(future_errc::promise_already_satisfied); 98167fd108SHoward Hinnant __state_ |= __constructed; 9910e4a48aSHoward Hinnant __thread_local_data()->__make_ready_at_thread_exit(this); 100167fd108SHoward Hinnant } 101167fd108SHoward Hinnant 102167fd108SHoward Hinnant void set_exception(exception_ptr __p)103167fd108SHoward Hinnant__assoc_sub_state::set_exception(exception_ptr __p) 104167fd108SHoward Hinnant { 105167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 106167fd108SHoward Hinnant if (__has_value()) 107934864bfSMarshall Clow __throw_future_error(future_errc::promise_already_satisfied); 108167fd108SHoward Hinnant __exception_ = __p; 109167fd108SHoward Hinnant __state_ |= ready; 110167fd108SHoward Hinnant __cv_.notify_all(); 111167fd108SHoward Hinnant } 112167fd108SHoward Hinnant 113167fd108SHoward Hinnant void set_exception_at_thread_exit(exception_ptr __p)114167fd108SHoward Hinnant__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p) 115167fd108SHoward Hinnant { 116167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 117167fd108SHoward Hinnant if (__has_value()) 118934864bfSMarshall Clow __throw_future_error(future_errc::promise_already_satisfied); 119167fd108SHoward Hinnant __exception_ = __p; 12010e4a48aSHoward Hinnant __thread_local_data()->__make_ready_at_thread_exit(this); 121167fd108SHoward Hinnant } 122167fd108SHoward Hinnant 123167fd108SHoward Hinnant void __make_ready()124167fd108SHoward Hinnant__assoc_sub_state::__make_ready() 125167fd108SHoward Hinnant { 126167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 127167fd108SHoward Hinnant __state_ |= ready; 128167fd108SHoward Hinnant __cv_.notify_all(); 129167fd108SHoward Hinnant } 130167fd108SHoward Hinnant 131167fd108SHoward Hinnant void copy()132167fd108SHoward Hinnant__assoc_sub_state::copy() 133167fd108SHoward Hinnant { 134167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 13527f000e1SHoward Hinnant __sub_wait(__lk); 136167fd108SHoward Hinnant if (__exception_ != nullptr) 137167fd108SHoward Hinnant rethrow_exception(__exception_); 138167fd108SHoward Hinnant } 139167fd108SHoward Hinnant 140167fd108SHoward Hinnant void wait()14127f000e1SHoward Hinnant__assoc_sub_state::wait() 142167fd108SHoward Hinnant { 143167fd108SHoward Hinnant unique_lock<mutex> __lk(__mut_); 14427f000e1SHoward Hinnant __sub_wait(__lk); 14527f000e1SHoward Hinnant } 14627f000e1SHoward Hinnant 14727f000e1SHoward Hinnant void __sub_wait(unique_lock<mutex> & __lk)14827f000e1SHoward Hinnant__assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk) 14927f000e1SHoward Hinnant { 15027f000e1SHoward Hinnant if (!__is_ready()) 15127f000e1SHoward Hinnant { 152c206366fSHoward Hinnant if (__state_ & static_cast<unsigned>(deferred)) 15327f000e1SHoward Hinnant { 154c206366fSHoward Hinnant __state_ &= ~static_cast<unsigned>(deferred); 15527f000e1SHoward Hinnant __lk.unlock(); 15627f000e1SHoward Hinnant __execute(); 15727f000e1SHoward Hinnant } 15827f000e1SHoward Hinnant else 159167fd108SHoward Hinnant while (!__is_ready()) 160167fd108SHoward Hinnant __cv_.wait(__lk); 161167fd108SHoward Hinnant } 16227f000e1SHoward Hinnant } 16327f000e1SHoward Hinnant 16427f000e1SHoward Hinnant void __execute()16527f000e1SHoward Hinnant__assoc_sub_state::__execute() 16627f000e1SHoward Hinnant { 167934864bfSMarshall Clow __throw_future_error(future_errc::no_state); 16827f000e1SHoward Hinnant } 169167fd108SHoward Hinnant future(__assoc_sub_state * __state)170167fd108SHoward Hinnantfuture<void>::future(__assoc_sub_state* __state) 171167fd108SHoward Hinnant : __state_(__state) 172167fd108SHoward Hinnant { 173616ef186SLouis Dionne __state_->__attach_future(); 174167fd108SHoward Hinnant } 175167fd108SHoward Hinnant ~future()176167fd108SHoward Hinnantfuture<void>::~future() 177167fd108SHoward Hinnant { 178167fd108SHoward Hinnant if (__state_) 179167fd108SHoward Hinnant __state_->__release_shared(); 180167fd108SHoward Hinnant } 181167fd108SHoward Hinnant 182167fd108SHoward Hinnant void get()183167fd108SHoward Hinnantfuture<void>::get() 184167fd108SHoward Hinnant { 18527f000e1SHoward Hinnant unique_ptr<__shared_count, __release_shared_count> __(__state_); 186167fd108SHoward Hinnant __assoc_sub_state* __s = __state_; 187167fd108SHoward Hinnant __state_ = nullptr; 18827f000e1SHoward Hinnant __s->copy(); 189167fd108SHoward Hinnant } 190167fd108SHoward Hinnant promise()191167fd108SHoward Hinnantpromise<void>::promise() 192167fd108SHoward Hinnant : __state_(new __assoc_sub_state) 193167fd108SHoward Hinnant { 194167fd108SHoward Hinnant } 195167fd108SHoward Hinnant ~promise()196167fd108SHoward Hinnantpromise<void>::~promise() 197167fd108SHoward Hinnant { 198167fd108SHoward Hinnant if (__state_) 199167fd108SHoward Hinnant { 200f520c144SAsiri Rathnayake #ifndef _LIBCPP_NO_EXCEPTIONS 201167fd108SHoward Hinnant if (!__state_->__has_value() && __state_->use_count() > 1) 202167fd108SHoward Hinnant __state_->set_exception(make_exception_ptr( 203167fd108SHoward Hinnant future_error(make_error_code(future_errc::broken_promise)) 204167fd108SHoward Hinnant )); 205f520c144SAsiri Rathnayake #endif // _LIBCPP_NO_EXCEPTIONS 206167fd108SHoward Hinnant __state_->__release_shared(); 207167fd108SHoward Hinnant } 208167fd108SHoward Hinnant } 209167fd108SHoward Hinnant 210167fd108SHoward Hinnant future<void> get_future()211167fd108SHoward Hinnantpromise<void>::get_future() 212167fd108SHoward Hinnant { 213167fd108SHoward Hinnant if (__state_ == nullptr) 214934864bfSMarshall Clow __throw_future_error(future_errc::no_state); 215167fd108SHoward Hinnant return future<void>(__state_); 216167fd108SHoward Hinnant } 217167fd108SHoward Hinnant 218167fd108SHoward Hinnant void set_value()219167fd108SHoward Hinnantpromise<void>::set_value() 220167fd108SHoward Hinnant { 221167fd108SHoward Hinnant if (__state_ == nullptr) 222934864bfSMarshall Clow __throw_future_error(future_errc::no_state); 223167fd108SHoward Hinnant __state_->set_value(); 224167fd108SHoward Hinnant } 225167fd108SHoward Hinnant 226167fd108SHoward Hinnant void set_exception(exception_ptr __p)227167fd108SHoward Hinnantpromise<void>::set_exception(exception_ptr __p) 228167fd108SHoward Hinnant { 229167fd108SHoward Hinnant if (__state_ == nullptr) 230934864bfSMarshall Clow __throw_future_error(future_errc::no_state); 231167fd108SHoward Hinnant __state_->set_exception(__p); 232167fd108SHoward Hinnant } 233167fd108SHoward Hinnant 234167fd108SHoward Hinnant void set_value_at_thread_exit()235167fd108SHoward Hinnantpromise<void>::set_value_at_thread_exit() 236167fd108SHoward Hinnant { 237167fd108SHoward Hinnant if (__state_ == nullptr) 238934864bfSMarshall Clow __throw_future_error(future_errc::no_state); 239167fd108SHoward Hinnant __state_->set_value_at_thread_exit(); 240167fd108SHoward Hinnant } 241167fd108SHoward Hinnant 242167fd108SHoward Hinnant void set_exception_at_thread_exit(exception_ptr __p)243167fd108SHoward Hinnantpromise<void>::set_exception_at_thread_exit(exception_ptr __p) 244167fd108SHoward Hinnant { 245167fd108SHoward Hinnant if (__state_ == nullptr) 246934864bfSMarshall Clow __throw_future_error(future_errc::no_state); 247167fd108SHoward Hinnant __state_->set_exception_at_thread_exit(__p); 248167fd108SHoward Hinnant } 249167fd108SHoward Hinnant ~shared_future()250ead85506SHoward Hinnantshared_future<void>::~shared_future() 251ead85506SHoward Hinnant { 252ead85506SHoward Hinnant if (__state_) 253ead85506SHoward Hinnant __state_->__release_shared(); 254ead85506SHoward Hinnant } 255ead85506SHoward Hinnant 256ead85506SHoward Hinnant shared_future<void>& operator =(const shared_future & __rhs)257ead85506SHoward Hinnantshared_future<void>::operator=(const shared_future& __rhs) 258ead85506SHoward Hinnant { 259ead85506SHoward Hinnant if (__rhs.__state_) 260ead85506SHoward Hinnant __rhs.__state_->__add_shared(); 261ead85506SHoward Hinnant if (__state_) 262ead85506SHoward Hinnant __state_->__release_shared(); 263ead85506SHoward Hinnant __state_ = __rhs.__state_; 264ead85506SHoward Hinnant return *this; 265ead85506SHoward Hinnant } 266ead85506SHoward Hinnant 267dae3481bSHoward Hinnant _LIBCPP_END_NAMESPACE_STD 268b3fcc67fSJonathan Roelofs 269b3fcc67fSJonathan Roelofs #endif // !_LIBCPP_HAS_NO_THREADS 270