1*58b9f456SAndroid Build Coastguard Worker// -*- C++ -*- 2*58b9f456SAndroid Build Coastguard Worker//===---------------------- condition_variable ----------------------------===// 3*58b9f456SAndroid Build Coastguard Worker// 4*58b9f456SAndroid Build Coastguard Worker// The LLVM Compiler Infrastructure 5*58b9f456SAndroid Build Coastguard Worker// 6*58b9f456SAndroid Build Coastguard Worker// This file is dual licensed under the MIT and the University of Illinois Open 7*58b9f456SAndroid Build Coastguard Worker// Source Licenses. See LICENSE.TXT for details. 8*58b9f456SAndroid Build Coastguard Worker// 9*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 10*58b9f456SAndroid Build Coastguard Worker 11*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_CONDITION_VARIABLE 12*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP_CONDITION_VARIABLE 13*58b9f456SAndroid Build Coastguard Worker 14*58b9f456SAndroid Build Coastguard Worker/* 15*58b9f456SAndroid Build Coastguard Worker condition_variable synopsis 16*58b9f456SAndroid Build Coastguard Worker 17*58b9f456SAndroid Build Coastguard Workernamespace std 18*58b9f456SAndroid Build Coastguard Worker{ 19*58b9f456SAndroid Build Coastguard Worker 20*58b9f456SAndroid Build Coastguard Workerenum class cv_status { no_timeout, timeout }; 21*58b9f456SAndroid Build Coastguard Worker 22*58b9f456SAndroid Build Coastguard Workerclass condition_variable 23*58b9f456SAndroid Build Coastguard Worker{ 24*58b9f456SAndroid Build Coastguard Workerpublic: 25*58b9f456SAndroid Build Coastguard Worker condition_variable(); 26*58b9f456SAndroid Build Coastguard Worker ~condition_variable(); 27*58b9f456SAndroid Build Coastguard Worker 28*58b9f456SAndroid Build Coastguard Worker condition_variable(const condition_variable&) = delete; 29*58b9f456SAndroid Build Coastguard Worker condition_variable& operator=(const condition_variable&) = delete; 30*58b9f456SAndroid Build Coastguard Worker 31*58b9f456SAndroid Build Coastguard Worker void notify_one() noexcept; 32*58b9f456SAndroid Build Coastguard Worker void notify_all() noexcept; 33*58b9f456SAndroid Build Coastguard Worker 34*58b9f456SAndroid Build Coastguard Worker void wait(unique_lock<mutex>& lock); 35*58b9f456SAndroid Build Coastguard Worker template <class Predicate> 36*58b9f456SAndroid Build Coastguard Worker void wait(unique_lock<mutex>& lock, Predicate pred); 37*58b9f456SAndroid Build Coastguard Worker 38*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration> 39*58b9f456SAndroid Build Coastguard Worker cv_status 40*58b9f456SAndroid Build Coastguard Worker wait_until(unique_lock<mutex>& lock, 41*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<Clock, Duration>& abs_time); 42*58b9f456SAndroid Build Coastguard Worker 43*58b9f456SAndroid Build Coastguard Worker template <class Clock, class Duration, class Predicate> 44*58b9f456SAndroid Build Coastguard Worker bool 45*58b9f456SAndroid Build Coastguard Worker wait_until(unique_lock<mutex>& lock, 46*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<Clock, Duration>& abs_time, 47*58b9f456SAndroid Build Coastguard Worker Predicate pred); 48*58b9f456SAndroid Build Coastguard Worker 49*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period> 50*58b9f456SAndroid Build Coastguard Worker cv_status 51*58b9f456SAndroid Build Coastguard Worker wait_for(unique_lock<mutex>& lock, 52*58b9f456SAndroid Build Coastguard Worker const chrono::duration<Rep, Period>& rel_time); 53*58b9f456SAndroid Build Coastguard Worker 54*58b9f456SAndroid Build Coastguard Worker template <class Rep, class Period, class Predicate> 55*58b9f456SAndroid Build Coastguard Worker bool 56*58b9f456SAndroid Build Coastguard Worker wait_for(unique_lock<mutex>& lock, 57*58b9f456SAndroid Build Coastguard Worker const chrono::duration<Rep, Period>& rel_time, 58*58b9f456SAndroid Build Coastguard Worker Predicate pred); 59*58b9f456SAndroid Build Coastguard Worker 60*58b9f456SAndroid Build Coastguard Worker typedef pthread_cond_t* native_handle_type; 61*58b9f456SAndroid Build Coastguard Worker native_handle_type native_handle(); 62*58b9f456SAndroid Build Coastguard Worker}; 63*58b9f456SAndroid Build Coastguard Worker 64*58b9f456SAndroid Build Coastguard Workervoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 65*58b9f456SAndroid Build Coastguard Worker 66*58b9f456SAndroid Build Coastguard Workerclass condition_variable_any 67*58b9f456SAndroid Build Coastguard Worker{ 68*58b9f456SAndroid Build Coastguard Workerpublic: 69*58b9f456SAndroid Build Coastguard Worker condition_variable_any(); 70*58b9f456SAndroid Build Coastguard Worker ~condition_variable_any(); 71*58b9f456SAndroid Build Coastguard Worker 72*58b9f456SAndroid Build Coastguard Worker condition_variable_any(const condition_variable_any&) = delete; 73*58b9f456SAndroid Build Coastguard Worker condition_variable_any& operator=(const condition_variable_any&) = delete; 74*58b9f456SAndroid Build Coastguard Worker 75*58b9f456SAndroid Build Coastguard Worker void notify_one() noexcept; 76*58b9f456SAndroid Build Coastguard Worker void notify_all() noexcept; 77*58b9f456SAndroid Build Coastguard Worker 78*58b9f456SAndroid Build Coastguard Worker template <class Lock> 79*58b9f456SAndroid Build Coastguard Worker void wait(Lock& lock); 80*58b9f456SAndroid Build Coastguard Worker template <class Lock, class Predicate> 81*58b9f456SAndroid Build Coastguard Worker void wait(Lock& lock, Predicate pred); 82*58b9f456SAndroid Build Coastguard Worker 83*58b9f456SAndroid Build Coastguard Worker template <class Lock, class Clock, class Duration> 84*58b9f456SAndroid Build Coastguard Worker cv_status 85*58b9f456SAndroid Build Coastguard Worker wait_until(Lock& lock, 86*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<Clock, Duration>& abs_time); 87*58b9f456SAndroid Build Coastguard Worker 88*58b9f456SAndroid Build Coastguard Worker template <class Lock, class Clock, class Duration, class Predicate> 89*58b9f456SAndroid Build Coastguard Worker bool 90*58b9f456SAndroid Build Coastguard Worker wait_until(Lock& lock, 91*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<Clock, Duration>& abs_time, 92*58b9f456SAndroid Build Coastguard Worker Predicate pred); 93*58b9f456SAndroid Build Coastguard Worker 94*58b9f456SAndroid Build Coastguard Worker template <class Lock, class Rep, class Period> 95*58b9f456SAndroid Build Coastguard Worker cv_status 96*58b9f456SAndroid Build Coastguard Worker wait_for(Lock& lock, 97*58b9f456SAndroid Build Coastguard Worker const chrono::duration<Rep, Period>& rel_time); 98*58b9f456SAndroid Build Coastguard Worker 99*58b9f456SAndroid Build Coastguard Worker template <class Lock, class Rep, class Period, class Predicate> 100*58b9f456SAndroid Build Coastguard Worker bool 101*58b9f456SAndroid Build Coastguard Worker wait_for(Lock& lock, 102*58b9f456SAndroid Build Coastguard Worker const chrono::duration<Rep, Period>& rel_time, 103*58b9f456SAndroid Build Coastguard Worker Predicate pred); 104*58b9f456SAndroid Build Coastguard Worker}; 105*58b9f456SAndroid Build Coastguard Worker 106*58b9f456SAndroid Build Coastguard Worker} // std 107*58b9f456SAndroid Build Coastguard Worker 108*58b9f456SAndroid Build Coastguard Worker*/ 109*58b9f456SAndroid Build Coastguard Worker 110*58b9f456SAndroid Build Coastguard Worker#include <__config> 111*58b9f456SAndroid Build Coastguard Worker#include <__mutex_base> 112*58b9f456SAndroid Build Coastguard Worker#include <memory> 113*58b9f456SAndroid Build Coastguard Worker 114*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 115*58b9f456SAndroid Build Coastguard Worker#pragma GCC system_header 116*58b9f456SAndroid Build Coastguard Worker#endif 117*58b9f456SAndroid Build Coastguard Worker 118*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_HAS_NO_THREADS 119*58b9f456SAndroid Build Coastguard Worker 120*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_STD 121*58b9f456SAndroid Build Coastguard Worker 122*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TYPE_VIS condition_variable_any 123*58b9f456SAndroid Build Coastguard Worker{ 124*58b9f456SAndroid Build Coastguard Worker condition_variable __cv_; 125*58b9f456SAndroid Build Coastguard Worker shared_ptr<mutex> __mut_; 126*58b9f456SAndroid Build Coastguard Workerpublic: 127*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 128*58b9f456SAndroid Build Coastguard Worker condition_variable_any(); 129*58b9f456SAndroid Build Coastguard Worker 130*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 131*58b9f456SAndroid Build Coastguard Worker void notify_one() _NOEXCEPT; 132*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 133*58b9f456SAndroid Build Coastguard Worker void notify_all() _NOEXCEPT; 134*58b9f456SAndroid Build Coastguard Worker 135*58b9f456SAndroid Build Coastguard Worker template <class _Lock> 136*58b9f456SAndroid Build Coastguard Worker _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 137*58b9f456SAndroid Build Coastguard Worker void wait(_Lock& __lock); 138*58b9f456SAndroid Build Coastguard Worker template <class _Lock, class _Predicate> 139*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 140*58b9f456SAndroid Build Coastguard Worker void wait(_Lock& __lock, _Predicate __pred); 141*58b9f456SAndroid Build Coastguard Worker 142*58b9f456SAndroid Build Coastguard Worker template <class _Lock, class _Clock, class _Duration> 143*58b9f456SAndroid Build Coastguard Worker _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS 144*58b9f456SAndroid Build Coastguard Worker cv_status 145*58b9f456SAndroid Build Coastguard Worker wait_until(_Lock& __lock, 146*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __t); 147*58b9f456SAndroid Build Coastguard Worker 148*58b9f456SAndroid Build Coastguard Worker template <class _Lock, class _Clock, class _Duration, class _Predicate> 149*58b9f456SAndroid Build Coastguard Worker bool 150*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 151*58b9f456SAndroid Build Coastguard Worker wait_until(_Lock& __lock, 152*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __t, 153*58b9f456SAndroid Build Coastguard Worker _Predicate __pred); 154*58b9f456SAndroid Build Coastguard Worker 155*58b9f456SAndroid Build Coastguard Worker template <class _Lock, class _Rep, class _Period> 156*58b9f456SAndroid Build Coastguard Worker cv_status 157*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 158*58b9f456SAndroid Build Coastguard Worker wait_for(_Lock& __lock, 159*58b9f456SAndroid Build Coastguard Worker const chrono::duration<_Rep, _Period>& __d); 160*58b9f456SAndroid Build Coastguard Worker 161*58b9f456SAndroid Build Coastguard Worker template <class _Lock, class _Rep, class _Period, class _Predicate> 162*58b9f456SAndroid Build Coastguard Worker bool 163*58b9f456SAndroid Build Coastguard Worker _LIBCPP_INLINE_VISIBILITY 164*58b9f456SAndroid Build Coastguard Worker wait_for(_Lock& __lock, 165*58b9f456SAndroid Build Coastguard Worker const chrono::duration<_Rep, _Period>& __d, 166*58b9f456SAndroid Build Coastguard Worker _Predicate __pred); 167*58b9f456SAndroid Build Coastguard Worker}; 168*58b9f456SAndroid Build Coastguard Worker 169*58b9f456SAndroid Build Coastguard Workerinline 170*58b9f456SAndroid Build Coastguard Workercondition_variable_any::condition_variable_any() 171*58b9f456SAndroid Build Coastguard Worker : __mut_(make_shared<mutex>()) {} 172*58b9f456SAndroid Build Coastguard Worker 173*58b9f456SAndroid Build Coastguard Workerinline 174*58b9f456SAndroid Build Coastguard Workervoid 175*58b9f456SAndroid Build Coastguard Workercondition_variable_any::notify_one() _NOEXCEPT 176*58b9f456SAndroid Build Coastguard Worker{ 177*58b9f456SAndroid Build Coastguard Worker {lock_guard<mutex> __lx(*__mut_);} 178*58b9f456SAndroid Build Coastguard Worker __cv_.notify_one(); 179*58b9f456SAndroid Build Coastguard Worker} 180*58b9f456SAndroid Build Coastguard Worker 181*58b9f456SAndroid Build Coastguard Workerinline 182*58b9f456SAndroid Build Coastguard Workervoid 183*58b9f456SAndroid Build Coastguard Workercondition_variable_any::notify_all() _NOEXCEPT 184*58b9f456SAndroid Build Coastguard Worker{ 185*58b9f456SAndroid Build Coastguard Worker {lock_guard<mutex> __lx(*__mut_);} 186*58b9f456SAndroid Build Coastguard Worker __cv_.notify_all(); 187*58b9f456SAndroid Build Coastguard Worker} 188*58b9f456SAndroid Build Coastguard Worker 189*58b9f456SAndroid Build Coastguard Workerstruct __lock_external 190*58b9f456SAndroid Build Coastguard Worker{ 191*58b9f456SAndroid Build Coastguard Worker template <class _Lock> 192*58b9f456SAndroid Build Coastguard Worker void operator()(_Lock* __m) {__m->lock();} 193*58b9f456SAndroid Build Coastguard Worker}; 194*58b9f456SAndroid Build Coastguard Worker 195*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock> 196*58b9f456SAndroid Build Coastguard Workervoid 197*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait(_Lock& __lock) 198*58b9f456SAndroid Build Coastguard Worker{ 199*58b9f456SAndroid Build Coastguard Worker shared_ptr<mutex> __mut = __mut_; 200*58b9f456SAndroid Build Coastguard Worker unique_lock<mutex> __lk(*__mut); 201*58b9f456SAndroid Build Coastguard Worker __lock.unlock(); 202*58b9f456SAndroid Build Coastguard Worker unique_ptr<_Lock, __lock_external> __lxx(&__lock); 203*58b9f456SAndroid Build Coastguard Worker lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 204*58b9f456SAndroid Build Coastguard Worker __cv_.wait(__lk); 205*58b9f456SAndroid Build Coastguard Worker} // __mut_.unlock(), __lock.lock() 206*58b9f456SAndroid Build Coastguard Worker 207*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Predicate> 208*58b9f456SAndroid Build Coastguard Workerinline 209*58b9f456SAndroid Build Coastguard Workervoid 210*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 211*58b9f456SAndroid Build Coastguard Worker{ 212*58b9f456SAndroid Build Coastguard Worker while (!__pred()) 213*58b9f456SAndroid Build Coastguard Worker wait(__lock); 214*58b9f456SAndroid Build Coastguard Worker} 215*58b9f456SAndroid Build Coastguard Worker 216*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Clock, class _Duration> 217*58b9f456SAndroid Build Coastguard Workercv_status 218*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_until(_Lock& __lock, 219*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __t) 220*58b9f456SAndroid Build Coastguard Worker{ 221*58b9f456SAndroid Build Coastguard Worker shared_ptr<mutex> __mut = __mut_; 222*58b9f456SAndroid Build Coastguard Worker unique_lock<mutex> __lk(*__mut); 223*58b9f456SAndroid Build Coastguard Worker __lock.unlock(); 224*58b9f456SAndroid Build Coastguard Worker unique_ptr<_Lock, __lock_external> __lxx(&__lock); 225*58b9f456SAndroid Build Coastguard Worker lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 226*58b9f456SAndroid Build Coastguard Worker return __cv_.wait_until(__lk, __t); 227*58b9f456SAndroid Build Coastguard Worker} // __mut_.unlock(), __lock.lock() 228*58b9f456SAndroid Build Coastguard Worker 229*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 230*58b9f456SAndroid Build Coastguard Workerinline 231*58b9f456SAndroid Build Coastguard Workerbool 232*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_until(_Lock& __lock, 233*58b9f456SAndroid Build Coastguard Worker const chrono::time_point<_Clock, _Duration>& __t, 234*58b9f456SAndroid Build Coastguard Worker _Predicate __pred) 235*58b9f456SAndroid Build Coastguard Worker{ 236*58b9f456SAndroid Build Coastguard Worker while (!__pred()) 237*58b9f456SAndroid Build Coastguard Worker if (wait_until(__lock, __t) == cv_status::timeout) 238*58b9f456SAndroid Build Coastguard Worker return __pred(); 239*58b9f456SAndroid Build Coastguard Worker return true; 240*58b9f456SAndroid Build Coastguard Worker} 241*58b9f456SAndroid Build Coastguard Worker 242*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Rep, class _Period> 243*58b9f456SAndroid Build Coastguard Workerinline 244*58b9f456SAndroid Build Coastguard Workercv_status 245*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_for(_Lock& __lock, 246*58b9f456SAndroid Build Coastguard Worker const chrono::duration<_Rep, _Period>& __d) 247*58b9f456SAndroid Build Coastguard Worker{ 248*58b9f456SAndroid Build Coastguard Worker return wait_until(__lock, chrono::steady_clock::now() + __d); 249*58b9f456SAndroid Build Coastguard Worker} 250*58b9f456SAndroid Build Coastguard Worker 251*58b9f456SAndroid Build Coastguard Workertemplate <class _Lock, class _Rep, class _Period, class _Predicate> 252*58b9f456SAndroid Build Coastguard Workerinline 253*58b9f456SAndroid Build Coastguard Workerbool 254*58b9f456SAndroid Build Coastguard Workercondition_variable_any::wait_for(_Lock& __lock, 255*58b9f456SAndroid Build Coastguard Worker const chrono::duration<_Rep, _Period>& __d, 256*58b9f456SAndroid Build Coastguard Worker _Predicate __pred) 257*58b9f456SAndroid Build Coastguard Worker{ 258*58b9f456SAndroid Build Coastguard Worker return wait_until(__lock, chrono::steady_clock::now() + __d, 259*58b9f456SAndroid Build Coastguard Worker _VSTD::move(__pred)); 260*58b9f456SAndroid Build Coastguard Worker} 261*58b9f456SAndroid Build Coastguard Worker 262*58b9f456SAndroid Build Coastguard Worker_LIBCPP_FUNC_VIS 263*58b9f456SAndroid Build Coastguard Workervoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 264*58b9f456SAndroid Build Coastguard Worker 265*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_STD 266*58b9f456SAndroid Build Coastguard Worker 267*58b9f456SAndroid Build Coastguard Worker#endif // !_LIBCPP_HAS_NO_THREADS 268*58b9f456SAndroid Build Coastguard Worker 269*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_CONDITION_VARIABLE 270