diff options
Diffstat (limited to 'libcxx/src')
-rw-r--r-- | libcxx/src/condition_variable.cpp | 6 | ||||
-rw-r--r-- | libcxx/src/future.cpp | 35 | ||||
-rw-r--r-- | libcxx/src/thread.cpp | 22 |
3 files changed, 63 insertions, 0 deletions
diff --git a/libcxx/src/condition_variable.cpp b/libcxx/src/condition_variable.cpp index 7373ec3ce5d..3bafa8c8cb8 100644 --- a/libcxx/src/condition_variable.cpp +++ b/libcxx/src/condition_variable.cpp @@ -61,4 +61,10 @@ condition_variable::__do_timed_wait(unique_lock<mutex>& lk, __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/libcxx/src/future.cpp b/libcxx/src/future.cpp index 924a6846869..ca3080382ee 100644 --- a/libcxx/src/future.cpp +++ b/libcxx/src/future.cpp @@ -257,4 +257,39 @@ shared_future<void>::operator=(const shared_future& __rhs) 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/libcxx/src/thread.cpp b/libcxx/src/thread.cpp index f8407067270..3d388e9f030 100644 --- a/libcxx/src/thread.cpp +++ b/libcxx/src/thread.cpp @@ -90,7 +90,10 @@ __thread_specific_ptr<__thread_struct> __thread_local_data; 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 @@ public: __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 @@ __thread_struct_imp::~__thread_struct_imp() } 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 @@ __thread_struct::~__thread_struct() } 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); |