diff options
author | Howard Hinnant <hhinnant@apple.com> | 2010-09-03 21:46:37 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2010-09-03 21:46:37 +0000 |
commit | b77c0c03bb5f48c7ff98aa0d8dd5c648e8a1a651 (patch) | |
tree | 51b1ae1903851f02fc0104ff07339673c7e83f73 /libcxx/src | |
parent | 005155e236afd14f9cc1342a213f050287e9bb26 (diff) | |
download | bcm5719-llvm-b77c0c03bb5f48c7ff98aa0d8dd5c648e8a1a651.tar.gz bcm5719-llvm-b77c0c03bb5f48c7ff98aa0d8dd5c648e8a1a651.zip |
[futures.atomic_future] and notify_all_at_thread_exit. This completes the header <future> and all of Chapter 30 (for C++0x enabled compilers).
llvm-svn: 113017
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); |