future continues ...
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@112284 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
157
src/future.cpp
157
src/future.cpp
@@ -60,4 +60,161 @@ future_error::future_error(error_code __ec)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::__on_zero_shared()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::set_value()
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
if (__has_value())
|
||||
throw future_error(make_error_code(future_errc::promise_already_satisfied));
|
||||
__state_ |= __constructed | ready;
|
||||
__lk.unlock();
|
||||
__cv_.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::set_value_at_thread_exit()
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
if (__has_value())
|
||||
throw future_error(make_error_code(future_errc::promise_already_satisfied));
|
||||
__state_ |= __constructed;
|
||||
__thread_local_data->__make_ready_at_thread_exit(this);
|
||||
__lk.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::set_exception(exception_ptr __p)
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
if (__has_value())
|
||||
throw future_error(make_error_code(future_errc::promise_already_satisfied));
|
||||
__exception_ = __p;
|
||||
__state_ |= ready;
|
||||
__lk.unlock();
|
||||
__cv_.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p)
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
if (__has_value())
|
||||
throw future_error(make_error_code(future_errc::promise_already_satisfied));
|
||||
__exception_ = __p;
|
||||
__thread_local_data->__make_ready_at_thread_exit(this);
|
||||
__lk.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::__make_ready()
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
__state_ |= ready;
|
||||
__lk.unlock();
|
||||
__cv_.notify_all();
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::copy()
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
while (!__is_ready())
|
||||
__cv_.wait(__lk);
|
||||
if (__exception_ != nullptr)
|
||||
rethrow_exception(__exception_);
|
||||
}
|
||||
|
||||
void
|
||||
__assoc_sub_state::wait() const
|
||||
{
|
||||
unique_lock<mutex> __lk(__mut_);
|
||||
while (!__is_ready())
|
||||
__cv_.wait(__lk);
|
||||
}
|
||||
|
||||
future<void>::future(__assoc_sub_state* __state)
|
||||
: __state_(__state)
|
||||
{
|
||||
if (__state_->__has_future_attached())
|
||||
throw future_error(make_error_code(future_errc::future_already_retrieved));
|
||||
__state_->__add_shared();
|
||||
}
|
||||
|
||||
future<void>::~future()
|
||||
{
|
||||
if (__state_)
|
||||
__state_->__release_shared();
|
||||
}
|
||||
|
||||
void
|
||||
future<void>::get()
|
||||
{
|
||||
__assoc_sub_state* __s = __state_;
|
||||
__state_ = nullptr;
|
||||
return __s->copy();
|
||||
}
|
||||
|
||||
promise<void>::promise()
|
||||
: __state_(new __assoc_sub_state)
|
||||
{
|
||||
}
|
||||
|
||||
promise<void>::~promise()
|
||||
{
|
||||
if (__state_)
|
||||
{
|
||||
if (!__state_->__has_value() && __state_->use_count() > 1)
|
||||
__state_->set_exception(make_exception_ptr(
|
||||
future_error(make_error_code(future_errc::broken_promise))
|
||||
));
|
||||
__state_->__release_shared();
|
||||
}
|
||||
}
|
||||
|
||||
future<void>
|
||||
promise<void>::get_future()
|
||||
{
|
||||
if (__state_ == nullptr)
|
||||
throw future_error(make_error_code(future_errc::no_state));
|
||||
return future<void>(__state_);
|
||||
}
|
||||
|
||||
void
|
||||
promise<void>::set_value()
|
||||
{
|
||||
if (__state_ == nullptr)
|
||||
throw future_error(make_error_code(future_errc::no_state));
|
||||
__state_->set_value();
|
||||
}
|
||||
|
||||
void
|
||||
promise<void>::set_exception(exception_ptr __p)
|
||||
{
|
||||
if (__state_ == nullptr)
|
||||
throw future_error(make_error_code(future_errc::no_state));
|
||||
__state_->set_exception(__p);
|
||||
}
|
||||
|
||||
void
|
||||
promise<void>::set_value_at_thread_exit()
|
||||
{
|
||||
if (__state_ == nullptr)
|
||||
throw future_error(make_error_code(future_errc::no_state));
|
||||
__state_->set_value_at_thread_exit();
|
||||
}
|
||||
|
||||
void
|
||||
promise<void>::set_exception_at_thread_exit(exception_ptr __p)
|
||||
{
|
||||
if (__state_ == nullptr)
|
||||
throw future_error(make_error_code(future_errc::no_state));
|
||||
__state_->set_exception_at_thread_exit(__p);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
Reference in New Issue
Block a user