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