1
//===------------------------- future.cpp ---------------------------------===//
3
// The LLVM Compiler Infrastructure
5
// This file is dual licensed under the MIT and the University of Illinois Open
6
// Source Licenses. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
13
_LIBCPP_BEGIN_NAMESPACE_STD
15
class _LIBCPP_HIDDEN __future_error_category
19
virtual const char* name() const _NOEXCEPT;
20
virtual string message(int ev) const;
24
__future_error_category::name() const _NOEXCEPT
30
__future_error_category::message(int ev) const
32
switch (static_cast<future_errc>(ev))
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.");
46
return string("unspecified future_errc value\n");
50
future_category() _NOEXCEPT
52
static __future_error_category __f;
56
future_error::future_error(error_code __ec)
57
: logic_error(__ec.message()),
62
future_error::~future_error() _NOEXCEPT
67
__assoc_sub_state::__on_zero_shared() _NOEXCEPT
73
__assoc_sub_state::set_value()
75
unique_lock<mutex> __lk(__mut_);
76
#ifndef _LIBCPP_NO_EXCEPTIONS
78
throw future_error(make_error_code(future_errc::promise_already_satisfied));
80
__state_ |= __constructed | ready;
86
__assoc_sub_state::set_value_at_thread_exit()
88
unique_lock<mutex> __lk(__mut_);
89
#ifndef _LIBCPP_NO_EXCEPTIONS
91
throw future_error(make_error_code(future_errc::promise_already_satisfied));
93
__state_ |= __constructed;
94
__thread_local_data()->__make_ready_at_thread_exit(this);
99
__assoc_sub_state::set_exception(exception_ptr __p)
101
unique_lock<mutex> __lk(__mut_);
102
#ifndef _LIBCPP_NO_EXCEPTIONS
104
throw future_error(make_error_code(future_errc::promise_already_satisfied));
113
__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p)
115
unique_lock<mutex> __lk(__mut_);
116
#ifndef _LIBCPP_NO_EXCEPTIONS
118
throw future_error(make_error_code(future_errc::promise_already_satisfied));
121
__thread_local_data()->__make_ready_at_thread_exit(this);
126
__assoc_sub_state::__make_ready()
128
unique_lock<mutex> __lk(__mut_);
135
__assoc_sub_state::copy()
137
unique_lock<mutex> __lk(__mut_);
139
if (__exception_ != nullptr)
140
rethrow_exception(__exception_);
144
__assoc_sub_state::wait()
146
unique_lock<mutex> __lk(__mut_);
151
__assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk)
155
if (__state_ & static_cast<unsigned>(deferred))
157
__state_ &= ~static_cast<unsigned>(deferred);
162
while (!__is_ready())
168
__assoc_sub_state::__execute()
170
#ifndef _LIBCPP_NO_EXCEPTIONS
171
throw future_error(make_error_code(future_errc::no_state));
175
future<void>::future(__assoc_sub_state* __state)
178
#ifndef _LIBCPP_NO_EXCEPTIONS
179
if (__state_->__has_future_attached())
180
throw future_error(make_error_code(future_errc::future_already_retrieved));
182
__state_->__add_shared();
183
__state_->__set_future_attached();
186
future<void>::~future()
189
__state_->__release_shared();
195
unique_ptr<__shared_count, __release_shared_count> __(__state_);
196
__assoc_sub_state* __s = __state_;
201
promise<void>::promise()
202
: __state_(new __assoc_sub_state)
206
promise<void>::~promise()
210
if (!__state_->__has_value() && __state_->use_count() > 1)
211
__state_->set_exception(make_exception_ptr(
212
future_error(make_error_code(future_errc::broken_promise))
214
__state_->__release_shared();
219
promise<void>::get_future()
221
#ifndef _LIBCPP_NO_EXCEPTIONS
222
if (__state_ == nullptr)
223
throw future_error(make_error_code(future_errc::no_state));
225
return future<void>(__state_);
229
promise<void>::set_value()
231
#ifndef _LIBCPP_NO_EXCEPTIONS
232
if (__state_ == nullptr)
233
throw future_error(make_error_code(future_errc::no_state));
235
__state_->set_value();
239
promise<void>::set_exception(exception_ptr __p)
241
#ifndef _LIBCPP_NO_EXCEPTIONS
242
if (__state_ == nullptr)
243
throw future_error(make_error_code(future_errc::no_state));
245
__state_->set_exception(__p);
249
promise<void>::set_value_at_thread_exit()
251
#ifndef _LIBCPP_NO_EXCEPTIONS
252
if (__state_ == nullptr)
253
throw future_error(make_error_code(future_errc::no_state));
255
__state_->set_value_at_thread_exit();
259
promise<void>::set_exception_at_thread_exit(exception_ptr __p)
261
#ifndef _LIBCPP_NO_EXCEPTIONS
262
if (__state_ == nullptr)
263
throw future_error(make_error_code(future_errc::no_state));
265
__state_->set_exception_at_thread_exit(__p);
268
shared_future<void>::~shared_future()
271
__state_->__release_shared();
275
shared_future<void>::operator=(const shared_future& __rhs)
278
__rhs.__state_->__add_shared();
280
__state_->__release_shared();
281
__state_ = __rhs.__state_;
285
_LIBCPP_END_NAMESPACE_STD