condition_variable revision 241903
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 31241903Sdim void notify_one() noexcept; 32241903Sdim 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 75241903Sdim void notify_one() noexcept; 76241903Sdim 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_LIBCPP_BEGIN_NAMESPACE_STD 119227825Stheraven 120227825Stheravenclass _LIBCPP_VISIBLE condition_variable_any 121227825Stheraven{ 122227825Stheraven condition_variable __cv_; 123227825Stheraven shared_ptr<mutex> __mut_; 124227825Stheravenpublic: 125227825Stheraven condition_variable_any(); 126227825Stheraven 127241903Sdim void notify_one() _NOEXCEPT; 128241903Sdim void notify_all() _NOEXCEPT; 129227825Stheraven 130227825Stheraven template <class _Lock> 131227825Stheraven void wait(_Lock& __lock); 132227825Stheraven template <class _Lock, class _Predicate> 133227825Stheraven void wait(_Lock& __lock, _Predicate __pred); 134227825Stheraven 135227825Stheraven template <class _Lock, class _Clock, class _Duration> 136227825Stheraven cv_status 137227825Stheraven wait_until(_Lock& __lock, 138227825Stheraven const chrono::time_point<_Clock, _Duration>& __t); 139227825Stheraven 140227825Stheraven template <class _Lock, class _Clock, class _Duration, class _Predicate> 141227825Stheraven bool 142227825Stheraven wait_until(_Lock& __lock, 143227825Stheraven const chrono::time_point<_Clock, _Duration>& __t, 144227825Stheraven _Predicate __pred); 145227825Stheraven 146227825Stheraven template <class _Lock, class _Rep, class _Period> 147227825Stheraven cv_status 148227825Stheraven wait_for(_Lock& __lock, 149227825Stheraven const chrono::duration<_Rep, _Period>& __d); 150227825Stheraven 151227825Stheraven template <class _Lock, class _Rep, class _Period, class _Predicate> 152227825Stheraven bool 153227825Stheraven wait_for(_Lock& __lock, 154227825Stheraven const chrono::duration<_Rep, _Period>& __d, 155227825Stheraven _Predicate __pred); 156227825Stheraven}; 157227825Stheraven 158227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 159227825Stheravencondition_variable_any::condition_variable_any() 160227825Stheraven : __mut_(make_shared<mutex>()) {} 161227825Stheraven 162227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 163227825Stheravenvoid 164241903Sdimcondition_variable_any::notify_one() _NOEXCEPT 165227825Stheraven{ 166227825Stheraven {lock_guard<mutex> _(*__mut_);} 167227825Stheraven __cv_.notify_one(); 168227825Stheraven} 169227825Stheraven 170227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 171227825Stheravenvoid 172241903Sdimcondition_variable_any::notify_all() _NOEXCEPT 173227825Stheraven{ 174227825Stheraven {lock_guard<mutex> _(*__mut_);} 175227825Stheraven __cv_.notify_all(); 176227825Stheraven} 177227825Stheraven 178227825Stheravenstruct __lock_external 179227825Stheraven{ 180227825Stheraven template <class _Lock> 181227825Stheraven void operator()(_Lock* __m) {__m->lock();} 182227825Stheraven}; 183227825Stheraven 184227825Stheraventemplate <class _Lock> 185227825Stheravenvoid 186227825Stheravencondition_variable_any::wait(_Lock& __lock) 187227825Stheraven{ 188227825Stheraven shared_ptr<mutex> __mut = __mut_; 189227825Stheraven unique_lock<mutex> __lk(*__mut); 190227825Stheraven __lock.unlock(); 191227825Stheraven unique_ptr<_Lock, __lock_external> __(&__lock); 192227825Stheraven lock_guard<unique_lock<mutex> > _(__lk, adopt_lock); 193227825Stheraven __cv_.wait(__lk); 194227825Stheraven} // __mut_.unlock(), __lock.lock() 195227825Stheraven 196227825Stheraventemplate <class _Lock, class _Predicate> 197227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 198227825Stheravenvoid 199227825Stheravencondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 200227825Stheraven{ 201227825Stheraven while (!__pred()) 202227825Stheraven wait(__lock); 203227825Stheraven} 204227825Stheraven 205227825Stheraventemplate <class _Lock, class _Clock, class _Duration> 206227825Stheravencv_status 207227825Stheravencondition_variable_any::wait_until(_Lock& __lock, 208227825Stheraven const chrono::time_point<_Clock, _Duration>& __t) 209227825Stheraven{ 210227825Stheraven shared_ptr<mutex> __mut = __mut_; 211227825Stheraven unique_lock<mutex> __lk(*__mut); 212227825Stheraven __lock.unlock(); 213227825Stheraven unique_ptr<_Lock, __lock_external> __(&__lock); 214227825Stheraven lock_guard<unique_lock<mutex> > _(__lk, adopt_lock); 215227825Stheraven return __cv_.wait_until(__lk, __t); 216227825Stheraven} // __mut_.unlock(), __lock.lock() 217227825Stheraven 218227825Stheraventemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 219227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 220227825Stheravenbool 221227825Stheravencondition_variable_any::wait_until(_Lock& __lock, 222227825Stheraven const chrono::time_point<_Clock, _Duration>& __t, 223227825Stheraven _Predicate __pred) 224227825Stheraven{ 225227825Stheraven while (!__pred()) 226227825Stheraven if (wait_until(__lock, __t) == cv_status::timeout) 227227825Stheraven return __pred(); 228227825Stheraven return true; 229227825Stheraven} 230227825Stheraven 231227825Stheraventemplate <class _Lock, class _Rep, class _Period> 232227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 233227825Stheravencv_status 234227825Stheravencondition_variable_any::wait_for(_Lock& __lock, 235227825Stheraven const chrono::duration<_Rep, _Period>& __d) 236227825Stheraven{ 237227825Stheraven return wait_until(__lock, chrono::steady_clock::now() + __d); 238227825Stheraven} 239227825Stheraven 240227825Stheraventemplate <class _Lock, class _Rep, class _Period, class _Predicate> 241227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 242227825Stheravenbool 243227825Stheravencondition_variable_any::wait_for(_Lock& __lock, 244227825Stheraven const chrono::duration<_Rep, _Period>& __d, 245227825Stheraven _Predicate __pred) 246227825Stheraven{ 247227825Stheraven return wait_until(__lock, chrono::steady_clock::now() + __d, 248227825Stheraven _VSTD::move(__pred)); 249227825Stheraven} 250227825Stheraven 251227825Stheraven_LIBCPP_VISIBLE 252227825Stheravenvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 253227825Stheraven 254227825Stheraven_LIBCPP_END_NAMESPACE_STD 255227825Stheraven 256227825Stheraven#endif // _LIBCPP_CONDITION_VARIABLE 257