diff options
author | Howard Hinnant <hhinnant@apple.com> | 2010-08-27 20:10:19 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2010-08-27 20:10:19 +0000 |
commit | 167fd1084bcb59dc26d3d3e9b993723800c478b9 (patch) | |
tree | 86321cc0089272615b6826ed3c3cc499206e283f /libcxx/src | |
parent | 212a492063944c97b20e009100c67c946644194c (diff) | |
download | bcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.tar.gz bcm5719-llvm-167fd1084bcb59dc26d3d3e9b993723800c478b9.zip |
future continues ...
llvm-svn: 112284
Diffstat (limited to 'libcxx/src')
-rw-r--r-- | libcxx/src/future.cpp | 157 | ||||
-rw-r--r-- | libcxx/src/thread.cpp | 55 |
2 files changed, 212 insertions, 0 deletions
diff --git a/libcxx/src/future.cpp b/libcxx/src/future.cpp index f9547c6609e..82b9b60ee4e 100644 --- a/libcxx/src/future.cpp +++ b/libcxx/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 diff --git a/libcxx/src/thread.cpp b/libcxx/src/thread.cpp index 992976500e5..f8407067270 100644 --- a/libcxx/src/thread.cpp +++ b/libcxx/src/thread.cpp @@ -9,6 +9,8 @@ #include "thread" #include "exception" +#include "vector" +#include "future" #include <sys/types.h> #include <sys/sysctl.h> @@ -81,4 +83,57 @@ sleep_for(const chrono::nanoseconds& ns) } // this_thread +__thread_specific_ptr<__thread_struct> __thread_local_data; + +// __thread_struct_imp + +class __thread_struct_imp +{ + typedef vector<__assoc_sub_state*> _AsyncStates; + _AsyncStates async_states_; + + __thread_struct_imp(const __thread_struct_imp&); + __thread_struct_imp& operator=(const __thread_struct_imp&); +public: + __thread_struct_imp() {} + ~__thread_struct_imp(); + + void __make_ready_at_thread_exit(__assoc_sub_state* __s); +}; + +__thread_struct_imp::~__thread_struct_imp() +{ + for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); + i != e; ++i) + { + (*i)->__make_ready(); + (*i)->__release_shared(); + } +} + +void +__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) +{ + async_states_.push_back(__s); + __s->__add_shared(); +} + +// __thread_struct + +__thread_struct::__thread_struct() + : __p_(new __thread_struct_imp) +{ +} + +__thread_struct::~__thread_struct() +{ + delete __p_; +} + +void +__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) +{ + __p_->__make_ready_at_thread_exit(__s); +} + _LIBCPP_END_NAMESPACE_STD |