condition_variable revision 278724
1227825Stheraven// -*- C++ -*- 2227825Stheraven//===---------------------- condition_variable ----------------------------===// 3227825Stheraven// 4227825Stheraven// The LLVM Compiler Infrastructure 5227825Stheraven// 6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 7227825Stheraven// Source Licenses. See LICENSE.TXT for details. 8227825Stheraven// 9227825Stheraven//===----------------------------------------------------------------------===// 10227825Stheraven 11227825Stheraven#ifndef _LIBCPP_CONDITION_VARIABLE 12227825Stheraven#define _LIBCPP_CONDITION_VARIABLE 13227825Stheraven 14227825Stheraven/* 15227825Stheraven condition_variable synopsis 16227825Stheraven 17227825Stheravennamespace std 18227825Stheraven{ 19227825Stheraven 20227825Stheravenenum class cv_status { no_timeout, timeout }; 21227825Stheraven 22227825Stheravenclass condition_variable 23227825Stheraven{ 24227825Stheravenpublic: 25227825Stheraven condition_variable(); 26227825Stheraven ~condition_variable(); 27227825Stheraven 28227825Stheraven condition_variable(const condition_variable&) = delete; 29227825Stheraven condition_variable& operator=(const condition_variable&) = delete; 30227825Stheraven 31227825Stheraven void notify_one() noexcept; 32227825Stheraven void notify_all() noexcept; 33227825Stheraven 34227825Stheraven void wait(unique_lock<mutex>& lock); 35227825Stheraven template <class Predicate> 36227825Stheraven void wait(unique_lock<mutex>& lock, Predicate pred); 37227825Stheraven 38227825Stheraven template <class Clock, class Duration> 39227825Stheraven cv_status 40227825Stheraven wait_until(unique_lock<mutex>& lock, 41227825Stheraven const chrono::time_point<Clock, Duration>& abs_time); 42227825Stheraven 43227825Stheraven template <class Clock, class Duration, class Predicate> 44227825Stheraven bool 45227825Stheraven wait_until(unique_lock<mutex>& lock, 46227825Stheraven const chrono::time_point<Clock, Duration>& abs_time, 47227825Stheraven Predicate pred); 48227825Stheraven 49227825Stheraven template <class Rep, class Period> 50227825Stheraven cv_status 51227825Stheraven wait_for(unique_lock<mutex>& lock, 52227825Stheraven const chrono::duration<Rep, Period>& rel_time); 53227825Stheraven 54227825Stheraven template <class Rep, class Period, class Predicate> 55227825Stheraven bool 56227825Stheraven wait_for(unique_lock<mutex>& lock, 57227825Stheraven const chrono::duration<Rep, Period>& rel_time, 58227825Stheraven Predicate pred); 59227825Stheraven 60227825Stheraven typedef pthread_cond_t* native_handle_type; 61227825Stheraven native_handle_type native_handle(); 62227825Stheraven}; 63227825Stheraven 64227825Stheravenvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 65227825Stheraven 66227825Stheravenclass condition_variable_any 67227825Stheraven{ 68227825Stheravenpublic: 69227825Stheraven condition_variable_any(); 70227825Stheraven ~condition_variable_any(); 71227825Stheraven 72227825Stheraven condition_variable_any(const condition_variable_any&) = delete; 73227825Stheraven condition_variable_any& operator=(const condition_variable_any&) = delete; 74227825Stheraven 75227825Stheraven void notify_one() noexcept; 76227825Stheraven void notify_all() noexcept; 77227825Stheraven 78227825Stheraven template <class Lock> 79227825Stheraven void wait(Lock& lock); 80227825Stheraven template <class Lock, class Predicate> 81227825Stheraven void wait(Lock& lock, Predicate pred); 82227825Stheraven 83227825Stheraven template <class Lock, class Clock, class Duration> 84227825Stheraven cv_status 85227825Stheraven wait_until(Lock& lock, 86227825Stheraven const chrono::time_point<Clock, Duration>& abs_time); 87227825Stheraven 88227825Stheraven template <class Lock, class Clock, class Duration, class Predicate> 89227825Stheraven bool 90227825Stheraven wait_until(Lock& lock, 91227825Stheraven const chrono::time_point<Clock, Duration>& abs_time, 92227825Stheraven Predicate pred); 93227825Stheraven 94227825Stheraven template <class Lock, class Rep, class Period> 95227825Stheraven cv_status 96227825Stheraven wait_for(Lock& lock, 97227825Stheraven const chrono::duration<Rep, Period>& rel_time); 98227825Stheraven 99227825Stheraven template <class Lock, class Rep, class Period, class Predicate> 100227825Stheraven bool 101227825Stheraven wait_for(Lock& lock, 102227825Stheraven const chrono::duration<Rep, Period>& rel_time, 103227825Stheraven Predicate pred); 104227825Stheraven}; 105227825Stheraven 106227825Stheraven} // std 107227825Stheraven 108227825Stheraven*/ 109227825Stheraven 110227825Stheraven#include <__config> 111227825Stheraven#include <__mutex_base> 112227825Stheraven#include <memory> 113227825Stheraven 114227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 115227825Stheraven#pragma GCC system_header 116227825Stheraven#endif 117227825Stheraven 118227825Stheraven#ifndef _LIBCPP_HAS_NO_THREADS 119227825Stheraven 120227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 121227825Stheraven 122227825Stheravenclass _LIBCPP_TYPE_VIS condition_variable_any 123227825Stheraven{ 124227825Stheraven condition_variable __cv_; 125227825Stheraven shared_ptr<mutex> __mut_; 126227825Stheravenpublic: 127227825Stheraven condition_variable_any(); 128227825Stheraven 129227825Stheraven void notify_one() _NOEXCEPT; 130227825Stheraven void notify_all() _NOEXCEPT; 131227825Stheraven 132227825Stheraven template <class _Lock> 133227825Stheraven void wait(_Lock& __lock); 134227825Stheraven template <class _Lock, class _Predicate> 135227825Stheraven void wait(_Lock& __lock, _Predicate __pred); 136227825Stheraven 137227825Stheraven template <class _Lock, class _Clock, class _Duration> 138227825Stheraven cv_status 139227825Stheraven wait_until(_Lock& __lock, 140227825Stheraven const chrono::time_point<_Clock, _Duration>& __t); 141227825Stheraven 142227825Stheraven template <class _Lock, class _Clock, class _Duration, class _Predicate> 143227825Stheraven bool 144227825Stheraven wait_until(_Lock& __lock, 145227825Stheraven const chrono::time_point<_Clock, _Duration>& __t, 146227825Stheraven _Predicate __pred); 147227825Stheraven 148227825Stheraven template <class _Lock, class _Rep, class _Period> 149227825Stheraven cv_status 150227825Stheraven wait_for(_Lock& __lock, 151227825Stheraven const chrono::duration<_Rep, _Period>& __d); 152227825Stheraven 153227825Stheraven template <class _Lock, class _Rep, class _Period, class _Predicate> 154227825Stheraven bool 155227825Stheraven wait_for(_Lock& __lock, 156227825Stheraven const chrono::duration<_Rep, _Period>& __d, 157227825Stheraven _Predicate __pred); 158227825Stheraven}; 159227825Stheraven 160227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 161227825Stheravencondition_variable_any::condition_variable_any() 162227825Stheraven : __mut_(make_shared<mutex>()) {} 163227825Stheraven 164227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 165227825Stheravenvoid 166227825Stheravencondition_variable_any::notify_one() _NOEXCEPT 167227825Stheraven{ 168227825Stheraven {lock_guard<mutex> __lx(*__mut_);} 169227825Stheraven __cv_.notify_one(); 170227825Stheraven} 171227825Stheraven 172227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 173227825Stheravenvoid 174227825Stheravencondition_variable_any::notify_all() _NOEXCEPT 175227825Stheraven{ 176227825Stheraven {lock_guard<mutex> __lx(*__mut_);} 177227825Stheraven __cv_.notify_all(); 178227825Stheraven} 179227825Stheraven 180227825Stheravenstruct __lock_external 181227825Stheraven{ 182227825Stheraven template <class _Lock> 183227825Stheraven void operator()(_Lock* __m) {__m->lock();} 184227825Stheraven}; 185227825Stheraven 186227825Stheraventemplate <class _Lock> 187227825Stheravenvoid 188227825Stheravencondition_variable_any::wait(_Lock& __lock) 189227825Stheraven{ 190227825Stheraven shared_ptr<mutex> __mut = __mut_; 191227825Stheraven unique_lock<mutex> __lk(*__mut); 192227825Stheraven __lock.unlock(); 193227825Stheraven unique_ptr<_Lock, __lock_external> __lxx(&__lock); 194227825Stheraven lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 195227825Stheraven __cv_.wait(__lk); 196227825Stheraven} // __mut_.unlock(), __lock.lock() 197227825Stheraven 198227825Stheraventemplate <class _Lock, class _Predicate> 199227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 200227825Stheravenvoid 201227825Stheravencondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 202227825Stheraven{ 203227825Stheraven while (!__pred()) 204227825Stheraven wait(__lock); 205227825Stheraven} 206227825Stheraven 207227825Stheraventemplate <class _Lock, class _Clock, class _Duration> 208227825Stheravencv_status 209227825Stheravencondition_variable_any::wait_until(_Lock& __lock, 210227825Stheraven const chrono::time_point<_Clock, _Duration>& __t) 211227825Stheraven{ 212227825Stheraven shared_ptr<mutex> __mut = __mut_; 213227825Stheraven unique_lock<mutex> __lk(*__mut); 214227825Stheraven __lock.unlock(); 215227825Stheraven unique_ptr<_Lock, __lock_external> __lxx(&__lock); 216227825Stheraven lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 217227825Stheraven return __cv_.wait_until(__lk, __t); 218227825Stheraven} // __mut_.unlock(), __lock.lock() 219227825Stheraven 220227825Stheraventemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 221227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 222227825Stheravenbool 223227825Stheravencondition_variable_any::wait_until(_Lock& __lock, 224227825Stheraven const chrono::time_point<_Clock, _Duration>& __t, 225227825Stheraven _Predicate __pred) 226227825Stheraven{ 227227825Stheraven while (!__pred()) 228227825Stheraven if (wait_until(__lock, __t) == cv_status::timeout) 229227825Stheraven return __pred(); 230227825Stheraven return true; 231227825Stheraven} 232227825Stheraven 233227825Stheraventemplate <class _Lock, class _Rep, class _Period> 234227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 235227825Stheravencv_status 236227825Stheravencondition_variable_any::wait_for(_Lock& __lock, 237227825Stheraven const chrono::duration<_Rep, _Period>& __d) 238227825Stheraven{ 239227825Stheraven return wait_until(__lock, chrono::steady_clock::now() + __d); 240227825Stheraven} 241227825Stheraven 242227825Stheraventemplate <class _Lock, class _Rep, class _Period, class _Predicate> 243227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 244227825Stheravenbool 245227825Stheravencondition_variable_any::wait_for(_Lock& __lock, 246227825Stheraven const chrono::duration<_Rep, _Period>& __d, 247227825Stheraven _Predicate __pred) 248227825Stheraven{ 249227825Stheraven return wait_until(__lock, chrono::steady_clock::now() + __d, 250227825Stheraven _VSTD::move(__pred)); 251227825Stheraven} 252227825Stheraven 253227825Stheraven_LIBCPP_FUNC_VIS 254227825Stheravenvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 255227825Stheraven 256227825Stheraven_LIBCPP_END_NAMESPACE_STD 257227825Stheraven 258227825Stheraven#endif // !_LIBCPP_HAS_NO_THREADS 259227825Stheraven 260227825Stheraven#endif // _LIBCPP_CONDITION_VARIABLE 261227825Stheraven