[futures.atomic_future] and notify_all_at_thread_exit. This completes the header <future> and all of Chapter 30 (for C++0x enabled compilers). git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@113017 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp index 7373ec3..3bafa8c 100644 --- a/src/condition_variable.cpp +++ b/src/condition_variable.cpp
@@ -61,4 +61,10 @@ __throw_system_error(ec, "condition_variable timed_wait failed"); } +void +notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) +{ + __thread_local_data->notify_all_at_thread_exit(&cond, lk.release()); +} + _LIBCPP_END_NAMESPACE_STD
diff --git a/src/future.cpp b/src/future.cpp index 924a684..ca30803 100644 --- a/src/future.cpp +++ b/src/future.cpp
@@ -257,4 +257,39 @@ return *this; } +atomic_future<void>::~atomic_future() +{ + if (__state_) + __state_->__release_shared(); +} + +atomic_future<void>& +atomic_future<void>::operator=(const atomic_future& __rhs) +{ + if (this != &__rhs) + { + unique_lock<mutex> __this(__mut_, defer_lock); + unique_lock<mutex> __that(__rhs.__mut_, defer_lock); + _STD::lock(__this, __that); + if (__rhs.__state_) + __rhs.__state_->__add_shared(); + if (__state_) + __state_->__release_shared(); + __state_ = __rhs.__state_; + } + return *this; +} + +void +atomic_future<void>::swap(atomic_future& __rhs) +{ + if (this != &__rhs) + { + unique_lock<mutex> __this(__mut_, defer_lock); + unique_lock<mutex> __that(__rhs.__mut_, defer_lock); + _STD::lock(__this, __that); + _STD::swap(__state_, __rhs.__state_); + } +} + _LIBCPP_END_NAMESPACE_STD
diff --git a/src/thread.cpp b/src/thread.cpp index f840706..3d388e9 100644 --- a/src/thread.cpp +++ b/src/thread.cpp
@@ -90,7 +90,10 @@ class __thread_struct_imp { typedef vector<__assoc_sub_state*> _AsyncStates; + typedef vector<pair<condition_variable*, mutex*> > _Notify; + _AsyncStates async_states_; + _Notify notify_; __thread_struct_imp(const __thread_struct_imp&); __thread_struct_imp& operator=(const __thread_struct_imp&); @@ -98,11 +101,18 @@ __thread_struct_imp() {} ~__thread_struct_imp(); + void notify_all_at_thread_exit(condition_variable* cv, mutex* m); void __make_ready_at_thread_exit(__assoc_sub_state* __s); }; __thread_struct_imp::~__thread_struct_imp() { + for (_Notify::iterator i = notify_.begin(), e = notify_.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); i != e; ++i) { @@ -112,6 +122,12 @@ } void +__thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m) +{ + notify_.push_back(pair<condition_variable*, mutex*>(cv, m)); +} + +void __thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) { async_states_.push_back(__s); @@ -131,6 +147,12 @@ } void +__thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m) +{ + __p_->notify_all_at_thread_exit(cv, m); +} + +void __thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) { __p_->__make_ready_at_thread_exit(__s);