1*4bdff4beSrobert //===----------------------------------------------------------------------===// 246035553Spatrick // 346035553Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 446035553Spatrick // See https://llvm.org/LICENSE.txt for license information. 546035553Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 646035553Spatrick // 746035553Spatrick //===----------------------------------------------------------------------===// 846035553Spatrick 9*4bdff4beSrobert #include <__config> 1046035553Spatrick 1146035553Spatrick #ifndef _LIBCPP_HAS_NO_THREADS 1246035553Spatrick 13*4bdff4beSrobert #include <future> 14*4bdff4beSrobert #include <string> 1546035553Spatrick 1646035553Spatrick _LIBCPP_BEGIN_NAMESPACE_STD 1746035553Spatrick 1846035553Spatrick class _LIBCPP_HIDDEN __future_error_category 1946035553Spatrick : public __do_message 2046035553Spatrick { 2146035553Spatrick public: 2276d0caaeSpatrick virtual const char* name() const noexcept; 2346035553Spatrick virtual string message(int ev) const; 2446035553Spatrick }; 2546035553Spatrick 2646035553Spatrick const char* name() const2776d0caaeSpatrick__future_error_category::name() const noexcept 2846035553Spatrick { 2946035553Spatrick return "future"; 3046035553Spatrick } 3146035553Spatrick 32*4bdff4beSrobert _LIBCPP_DIAGNOSTIC_PUSH 33*4bdff4beSrobert _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wswitch") 34*4bdff4beSrobert _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wswitch") 3546035553Spatrick 3646035553Spatrick string message(int ev) const3746035553Spatrick__future_error_category::message(int ev) const 3846035553Spatrick { 3946035553Spatrick switch (static_cast<future_errc>(ev)) 4046035553Spatrick { 4146035553Spatrick case future_errc(0): // For backwards compatibility with C++11 (LWG 2056) 4246035553Spatrick case future_errc::broken_promise: 4346035553Spatrick return string("The associated promise has been destructed prior " 4446035553Spatrick "to the associated state becoming ready."); 4546035553Spatrick case future_errc::future_already_retrieved: 4646035553Spatrick return string("The future has already been retrieved from " 4746035553Spatrick "the promise or packaged_task."); 4846035553Spatrick case future_errc::promise_already_satisfied: 4946035553Spatrick return string("The state of the promise has already been set."); 5046035553Spatrick case future_errc::no_state: 5146035553Spatrick return string("Operation not permitted on an object without " 5246035553Spatrick "an associated state."); 5346035553Spatrick } 5446035553Spatrick return string("unspecified future_errc value\n"); 5546035553Spatrick } 5646035553Spatrick 57*4bdff4beSrobert _LIBCPP_DIAGNOSTIC_POP 5846035553Spatrick 5946035553Spatrick const error_category& future_category()6076d0caaeSpatrickfuture_category() noexcept 6146035553Spatrick { 6246035553Spatrick static __future_error_category __f; 6346035553Spatrick return __f; 6446035553Spatrick } 6546035553Spatrick future_error(error_code __ec)6646035553Spatrickfuture_error::future_error(error_code __ec) 6746035553Spatrick : logic_error(__ec.message()), 6846035553Spatrick __ec_(__ec) 6946035553Spatrick { 7046035553Spatrick } 7146035553Spatrick ~future_error()7276d0caaeSpatrickfuture_error::~future_error() noexcept 7346035553Spatrick { 7446035553Spatrick } 7546035553Spatrick 7646035553Spatrick void __on_zero_shared()7776d0caaeSpatrick__assoc_sub_state::__on_zero_shared() noexcept 7846035553Spatrick { 7946035553Spatrick delete this; 8046035553Spatrick } 8146035553Spatrick 8246035553Spatrick void set_value()8346035553Spatrick__assoc_sub_state::set_value() 8446035553Spatrick { 8546035553Spatrick unique_lock<mutex> __lk(__mut_); 8646035553Spatrick if (__has_value()) 8746035553Spatrick __throw_future_error(future_errc::promise_already_satisfied); 8846035553Spatrick __state_ |= __constructed | ready; 8946035553Spatrick __cv_.notify_all(); 9046035553Spatrick } 9146035553Spatrick 9246035553Spatrick void set_value_at_thread_exit()9346035553Spatrick__assoc_sub_state::set_value_at_thread_exit() 9446035553Spatrick { 9546035553Spatrick unique_lock<mutex> __lk(__mut_); 9646035553Spatrick if (__has_value()) 9746035553Spatrick __throw_future_error(future_errc::promise_already_satisfied); 9846035553Spatrick __state_ |= __constructed; 9946035553Spatrick __thread_local_data()->__make_ready_at_thread_exit(this); 10046035553Spatrick } 10146035553Spatrick 10246035553Spatrick void set_exception(exception_ptr __p)10346035553Spatrick__assoc_sub_state::set_exception(exception_ptr __p) 10446035553Spatrick { 10546035553Spatrick unique_lock<mutex> __lk(__mut_); 10646035553Spatrick if (__has_value()) 10746035553Spatrick __throw_future_error(future_errc::promise_already_satisfied); 10846035553Spatrick __exception_ = __p; 10946035553Spatrick __state_ |= ready; 11046035553Spatrick __cv_.notify_all(); 11146035553Spatrick } 11246035553Spatrick 11346035553Spatrick void set_exception_at_thread_exit(exception_ptr __p)11446035553Spatrick__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p) 11546035553Spatrick { 11646035553Spatrick unique_lock<mutex> __lk(__mut_); 11746035553Spatrick if (__has_value()) 11846035553Spatrick __throw_future_error(future_errc::promise_already_satisfied); 11946035553Spatrick __exception_ = __p; 12046035553Spatrick __thread_local_data()->__make_ready_at_thread_exit(this); 12146035553Spatrick } 12246035553Spatrick 12346035553Spatrick void __make_ready()12446035553Spatrick__assoc_sub_state::__make_ready() 12546035553Spatrick { 12646035553Spatrick unique_lock<mutex> __lk(__mut_); 12746035553Spatrick __state_ |= ready; 12846035553Spatrick __cv_.notify_all(); 12946035553Spatrick } 13046035553Spatrick 13146035553Spatrick void copy()13246035553Spatrick__assoc_sub_state::copy() 13346035553Spatrick { 13446035553Spatrick unique_lock<mutex> __lk(__mut_); 13546035553Spatrick __sub_wait(__lk); 13646035553Spatrick if (__exception_ != nullptr) 13746035553Spatrick rethrow_exception(__exception_); 13846035553Spatrick } 13946035553Spatrick 14046035553Spatrick void wait()14146035553Spatrick__assoc_sub_state::wait() 14246035553Spatrick { 14346035553Spatrick unique_lock<mutex> __lk(__mut_); 14446035553Spatrick __sub_wait(__lk); 14546035553Spatrick } 14646035553Spatrick 14746035553Spatrick void __sub_wait(unique_lock<mutex> & __lk)14846035553Spatrick__assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk) 14946035553Spatrick { 15046035553Spatrick if (!__is_ready()) 15146035553Spatrick { 15246035553Spatrick if (__state_ & static_cast<unsigned>(deferred)) 15346035553Spatrick { 15446035553Spatrick __state_ &= ~static_cast<unsigned>(deferred); 15546035553Spatrick __lk.unlock(); 15646035553Spatrick __execute(); 15746035553Spatrick } 15846035553Spatrick else 15946035553Spatrick while (!__is_ready()) 16046035553Spatrick __cv_.wait(__lk); 16146035553Spatrick } 16246035553Spatrick } 16346035553Spatrick 16446035553Spatrick void __execute()16546035553Spatrick__assoc_sub_state::__execute() 16646035553Spatrick { 16746035553Spatrick __throw_future_error(future_errc::no_state); 16846035553Spatrick } 16946035553Spatrick future(__assoc_sub_state * __state)17046035553Spatrickfuture<void>::future(__assoc_sub_state* __state) 17146035553Spatrick : __state_(__state) 17246035553Spatrick { 17346035553Spatrick __state_->__attach_future(); 17446035553Spatrick } 17546035553Spatrick ~future()17646035553Spatrickfuture<void>::~future() 17746035553Spatrick { 17846035553Spatrick if (__state_) 17946035553Spatrick __state_->__release_shared(); 18046035553Spatrick } 18146035553Spatrick 18246035553Spatrick void get()18346035553Spatrickfuture<void>::get() 18446035553Spatrick { 18546035553Spatrick unique_ptr<__shared_count, __release_shared_count> __(__state_); 18646035553Spatrick __assoc_sub_state* __s = __state_; 18746035553Spatrick __state_ = nullptr; 18846035553Spatrick __s->copy(); 18946035553Spatrick } 19046035553Spatrick promise()19146035553Spatrickpromise<void>::promise() 19246035553Spatrick : __state_(new __assoc_sub_state) 19346035553Spatrick { 19446035553Spatrick } 19546035553Spatrick ~promise()19646035553Spatrickpromise<void>::~promise() 19746035553Spatrick { 19846035553Spatrick if (__state_) 19946035553Spatrick { 20046035553Spatrick #ifndef _LIBCPP_NO_EXCEPTIONS 20146035553Spatrick if (!__state_->__has_value() && __state_->use_count() > 1) 20246035553Spatrick __state_->set_exception(make_exception_ptr( 20346035553Spatrick future_error(make_error_code(future_errc::broken_promise)) 20446035553Spatrick )); 20546035553Spatrick #endif // _LIBCPP_NO_EXCEPTIONS 20646035553Spatrick __state_->__release_shared(); 20746035553Spatrick } 20846035553Spatrick } 20946035553Spatrick 21046035553Spatrick future<void> get_future()21146035553Spatrickpromise<void>::get_future() 21246035553Spatrick { 21346035553Spatrick if (__state_ == nullptr) 21446035553Spatrick __throw_future_error(future_errc::no_state); 21546035553Spatrick return future<void>(__state_); 21646035553Spatrick } 21746035553Spatrick 21846035553Spatrick void set_value()21946035553Spatrickpromise<void>::set_value() 22046035553Spatrick { 22146035553Spatrick if (__state_ == nullptr) 22246035553Spatrick __throw_future_error(future_errc::no_state); 22346035553Spatrick __state_->set_value(); 22446035553Spatrick } 22546035553Spatrick 22646035553Spatrick void set_exception(exception_ptr __p)22746035553Spatrickpromise<void>::set_exception(exception_ptr __p) 22846035553Spatrick { 22946035553Spatrick if (__state_ == nullptr) 23046035553Spatrick __throw_future_error(future_errc::no_state); 23146035553Spatrick __state_->set_exception(__p); 23246035553Spatrick } 23346035553Spatrick 23446035553Spatrick void set_value_at_thread_exit()23546035553Spatrickpromise<void>::set_value_at_thread_exit() 23646035553Spatrick { 23746035553Spatrick if (__state_ == nullptr) 23846035553Spatrick __throw_future_error(future_errc::no_state); 23946035553Spatrick __state_->set_value_at_thread_exit(); 24046035553Spatrick } 24146035553Spatrick 24246035553Spatrick void set_exception_at_thread_exit(exception_ptr __p)24346035553Spatrickpromise<void>::set_exception_at_thread_exit(exception_ptr __p) 24446035553Spatrick { 24546035553Spatrick if (__state_ == nullptr) 24646035553Spatrick __throw_future_error(future_errc::no_state); 24746035553Spatrick __state_->set_exception_at_thread_exit(__p); 24846035553Spatrick } 24946035553Spatrick ~shared_future()25046035553Spatrickshared_future<void>::~shared_future() 25146035553Spatrick { 25246035553Spatrick if (__state_) 25346035553Spatrick __state_->__release_shared(); 25446035553Spatrick } 25546035553Spatrick 25646035553Spatrick shared_future<void>& operator =(const shared_future & __rhs)25746035553Spatrickshared_future<void>::operator=(const shared_future& __rhs) 25846035553Spatrick { 25946035553Spatrick if (__rhs.__state_) 26046035553Spatrick __rhs.__state_->__add_shared(); 26146035553Spatrick if (__state_) 26246035553Spatrick __state_->__release_shared(); 26346035553Spatrick __state_ = __rhs.__state_; 26446035553Spatrick return *this; 26546035553Spatrick } 26646035553Spatrick 26746035553Spatrick _LIBCPP_END_NAMESPACE_STD 26846035553Spatrick 26946035553Spatrick #endif // !_LIBCPP_HAS_NO_THREADS 270