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