condition_variable revision 303975
11541Srgrimes// -*- C++ -*- 21541Srgrimes//===---------------------- condition_variable ----------------------------===// 31541Srgrimes// 41541Srgrimes// The LLVM Compiler Infrastructure 51541Srgrimes// 61541Srgrimes// This file is dual licensed under the MIT and the University of Illinois Open 71541Srgrimes// Source Licenses. See LICENSE.TXT for details. 81541Srgrimes// 91541Srgrimes//===----------------------------------------------------------------------===// 101541Srgrimes 111541Srgrimes#ifndef _LIBCPP_CONDITION_VARIABLE 121541Srgrimes#define _LIBCPP_CONDITION_VARIABLE 131541Srgrimes 141541Srgrimes/* 151541Srgrimes condition_variable synopsis 161541Srgrimes 171541Srgrimesnamespace std 181541Srgrimes{ 191541Srgrimes 201541Srgrimesenum class cv_status { no_timeout, timeout }; 211541Srgrimes 221541Srgrimesclass condition_variable 231541Srgrimes{ 241541Srgrimespublic: 251541Srgrimes condition_variable(); 261541Srgrimes ~condition_variable(); 271541Srgrimes 281541Srgrimes condition_variable(const condition_variable&) = delete; 291541Srgrimes condition_variable& operator=(const condition_variable&) = delete; 301541Srgrimes 311541Srgrimes void notify_one() noexcept; 321541Srgrimes void notify_all() noexcept; 3314478Shsu 3416363Sasami void wait(unique_lock<mutex>& lock); 351541Srgrimes template <class Predicate> 361541Srgrimes void wait(unique_lock<mutex>& lock, Predicate pred); 372165Spaul 385052Sbde template <class Clock, class Duration> 392165Spaul cv_status 401541Srgrimes wait_until(unique_lock<mutex>& lock, 411541Srgrimes const chrono::time_point<Clock, Duration>& abs_time); 421541Srgrimes 431541Srgrimes template <class Clock, class Duration, class Predicate> 441541Srgrimes bool 451541Srgrimes wait_until(unique_lock<mutex>& lock, 461541Srgrimes const chrono::time_point<Clock, Duration>& abs_time, 471541Srgrimes Predicate pred); 481541Srgrimes 491541Srgrimes template <class Rep, class Period> 501541Srgrimes cv_status 511541Srgrimes wait_for(unique_lock<mutex>& lock, 521541Srgrimes const chrono::duration<Rep, Period>& rel_time); 531541Srgrimes 544027Sphk template <class Rep, class Period, class Predicate> 551541Srgrimes bool 561541Srgrimes wait_for(unique_lock<mutex>& lock, 571541Srgrimes const chrono::duration<Rep, Period>& rel_time, 581541Srgrimes Predicate pred); 591541Srgrimes 601541Srgrimes typedef pthread_cond_t* native_handle_type; 611541Srgrimes native_handle_type native_handle(); 621541Srgrimes}; 631541Srgrimes 641541Srgrimesvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 651541Srgrimes 661541Srgrimesclass condition_variable_any 6714478Shsu{ 681541Srgrimespublic: 691541Srgrimes condition_variable_any(); 701541Srgrimes ~condition_variable_any(); 711541Srgrimes 725052Sbde condition_variable_any(const condition_variable_any&) = delete; 735052Sbde condition_variable_any& operator=(const condition_variable_any&) = delete; 745052Sbde 751541Srgrimes void notify_one() noexcept; 761541Srgrimes void notify_all() noexcept; 771541Srgrimes 7814478Shsu template <class Lock> 7914478Shsu void wait(Lock& lock); 8014478Shsu template <class Lock, class Predicate> 8114478Shsu void wait(Lock& lock, Predicate pred); 8214478Shsu 8314478Shsu template <class Lock, class Clock, class Duration> 841541Srgrimes cv_status 851541Srgrimes wait_until(Lock& lock, 861541Srgrimes const chrono::time_point<Clock, Duration>& abs_time); 871541Srgrimes 881541Srgrimes template <class Lock, class Clock, class Duration, class Predicate> 891541Srgrimes bool 901541Srgrimes wait_until(Lock& lock, 911541Srgrimes const chrono::time_point<Clock, Duration>& abs_time, 9214478Shsu Predicate pred); 931541Srgrimes 941541Srgrimes template <class Lock, class Rep, class Period> 958876Srgrimes cv_status 961541Srgrimes wait_for(Lock& lock, 971541Srgrimes const chrono::duration<Rep, Period>& rel_time); 981541Srgrimes 998876Srgrimes template <class Lock, class Rep, class Period, class Predicate> 1008876Srgrimes bool 1011541Srgrimes wait_for(Lock& lock, 1021541Srgrimes const chrono::duration<Rep, Period>& rel_time, 1031541Srgrimes Predicate pred); 1041541Srgrimes}; 10514478Shsu 1061541Srgrimes} // std 10714478Shsu 10814478Shsu*/ 10914478Shsu 11014478Shsu#include <__config> 11114478Shsu#include <__mutex_base> 11214478Shsu#include <memory> 11314478Shsu 1141541Srgrimes#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 11514478Shsu#pragma GCC system_header 11614478Shsu#endif 11714478Shsu 11814478Shsu#ifndef _LIBCPP_HAS_NO_THREADS 1191541Srgrimes 12014478Shsu_LIBCPP_BEGIN_NAMESPACE_STD 12114478Shsu 1221541Srgrimesclass _LIBCPP_TYPE_VIS condition_variable_any 12314478Shsu{ 12414478Shsu condition_variable __cv_; 1251541Srgrimes shared_ptr<mutex> __mut_; 12614478Shsupublic: 1271541Srgrimes _LIBCPP_INLINE_VISIBILITY 1281541Srgrimes condition_variable_any(); 1291541Srgrimes 1301541Srgrimes _LIBCPP_INLINE_VISIBILITY 1311541Srgrimes void notify_one() _NOEXCEPT; 13214478Shsu _LIBCPP_INLINE_VISIBILITY 13314478Shsu void notify_all() _NOEXCEPT; 13414478Shsu 13514478Shsu template <class _Lock> 13614478Shsu void wait(_Lock& __lock); 13714478Shsu template <class _Lock, class _Predicate> 13814478Shsu _LIBCPP_INLINE_VISIBILITY 13914478Shsu void wait(_Lock& __lock, _Predicate __pred); 14014478Shsu 14114478Shsu template <class _Lock, class _Clock, class _Duration> 14214478Shsu cv_status 14314478Shsu wait_until(_Lock& __lock, 1441541Srgrimes const chrono::time_point<_Clock, _Duration>& __t); 14514478Shsu 14614478Shsu template <class _Lock, class _Clock, class _Duration, class _Predicate> 14714478Shsu bool 14814478Shsu _LIBCPP_INLINE_VISIBILITY 14914478Shsu wait_until(_Lock& __lock, 15014478Shsu const chrono::time_point<_Clock, _Duration>& __t, 15114478Shsu _Predicate __pred); 1521541Srgrimes 15314478Shsu template <class _Lock, class _Rep, class _Period> 1541541Srgrimes cv_status 15514478Shsu _LIBCPP_INLINE_VISIBILITY 15614478Shsu wait_for(_Lock& __lock, 15714478Shsu const chrono::duration<_Rep, _Period>& __d); 1581541Srgrimes 1591541Srgrimes template <class _Lock, class _Rep, class _Period, class _Predicate> 16014478Shsu bool 16114478Shsu _LIBCPP_INLINE_VISIBILITY 16214478Shsu wait_for(_Lock& __lock, 1631541Srgrimes const chrono::duration<_Rep, _Period>& __d, 16414478Shsu _Predicate __pred); 16514478Shsu}; 16614478Shsu 16714478Shsuinline 16814478Shsucondition_variable_any::condition_variable_any() 1691541Srgrimes : __mut_(make_shared<mutex>()) {} 17014478Shsu 17114478Shsuinline 1721541Srgrimesvoid 1731541Srgrimescondition_variable_any::notify_one() _NOEXCEPT 1741541Srgrimes{ 1751541Srgrimes {lock_guard<mutex> __lx(*__mut_);} 1761541Srgrimes __cv_.notify_one(); 1771541Srgrimes} 1781541Srgrimes 1791541Srgrimesinline 1801541Srgrimesvoid 1811541Srgrimescondition_variable_any::notify_all() _NOEXCEPT 1821541Srgrimes{ 1831541Srgrimes {lock_guard<mutex> __lx(*__mut_);} 1841541Srgrimes __cv_.notify_all(); 1851541Srgrimes} 1861541Srgrimes 1871541Srgrimesstruct __lock_external 1881541Srgrimes{ 1891541Srgrimes template <class _Lock> 1901541Srgrimes void operator()(_Lock* __m) {__m->lock();} 1911541Srgrimes}; 1921541Srgrimes 1931541Srgrimestemplate <class _Lock> 1941541Srgrimesvoid 1951541Srgrimescondition_variable_any::wait(_Lock& __lock) 1961541Srgrimes{ 1971541Srgrimes shared_ptr<mutex> __mut = __mut_; 1981541Srgrimes unique_lock<mutex> __lk(*__mut); 1991541Srgrimes __lock.unlock(); 20015571Sasami unique_ptr<_Lock, __lock_external> __lxx(&__lock); 2011541Srgrimes lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 20216363Sasami __cv_.wait(__lk); 20316363Sasami} // __mut_.unlock(), __lock.lock() 20416363Sasami 20516363Sasamitemplate <class _Lock, class _Predicate> 2061541Srgrimesinline 2071541Srgrimesvoid 2081541Srgrimescondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 2091541Srgrimes{ 2101541Srgrimes while (!__pred()) 2111541Srgrimes wait(__lock); 2121541Srgrimes} 2131541Srgrimes 2141541Srgrimestemplate <class _Lock, class _Clock, class _Duration> 2151541Srgrimescv_status 2161541Srgrimescondition_variable_any::wait_until(_Lock& __lock, 2171541Srgrimes const chrono::time_point<_Clock, _Duration>& __t) 2181541Srgrimes{ 21915571Sasami shared_ptr<mutex> __mut = __mut_; 22014478Shsu unique_lock<mutex> __lk(*__mut); 2211541Srgrimes __lock.unlock(); 2221541Srgrimes unique_ptr<_Lock, __lock_external> __lxx(&__lock); 2231541Srgrimes lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 2241541Srgrimes return __cv_.wait_until(__lk, __t); 2251541Srgrimes} // __mut_.unlock(), __lock.lock() 2261541Srgrimes 2271541Srgrimestemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 2281541Srgrimesinline 2291541Srgrimesbool 2301541Srgrimescondition_variable_any::wait_until(_Lock& __lock, 2311541Srgrimes const chrono::time_point<_Clock, _Duration>& __t, 2321541Srgrimes _Predicate __pred) 2331541Srgrimes{ 2341541Srgrimes while (!__pred()) 2351541Srgrimes if (wait_until(__lock, __t) == cv_status::timeout) 2361541Srgrimes return __pred(); 2371541Srgrimes return true; 2381541Srgrimes} 2391541Srgrimes 2401541Srgrimestemplate <class _Lock, class _Rep, class _Period> 2411541Srgrimesinline 2421541Srgrimescv_status 2431541Srgrimescondition_variable_any::wait_for(_Lock& __lock, 2441541Srgrimes const chrono::duration<_Rep, _Period>& __d) 2451541Srgrimes{ 2461541Srgrimes return wait_until(__lock, chrono::steady_clock::now() + __d); 2471541Srgrimes} 2481541Srgrimes 2491541Srgrimestemplate <class _Lock, class _Rep, class _Period, class _Predicate> 2501541Srgrimesinline 2511541Srgrimesbool 2521541Srgrimescondition_variable_any::wait_for(_Lock& __lock, 2531541Srgrimes const chrono::duration<_Rep, _Period>& __d, 2541541Srgrimes _Predicate __pred) 2551541Srgrimes{ 2561541Srgrimes return wait_until(__lock, chrono::steady_clock::now() + __d, 2571541Srgrimes _VSTD::move(__pred)); 2581541Srgrimes} 2591541Srgrimes 2601541Srgrimes_LIBCPP_FUNC_VIS 26114478Shsuvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 2621541Srgrimes 2631541Srgrimes_LIBCPP_END_NAMESPACE_STD 2641541Srgrimes 2651541Srgrimes#endif // !_LIBCPP_HAS_NO_THREADS 2661541Srgrimes 2671541Srgrimes#endif // _LIBCPP_CONDITION_VARIABLE 2681541Srgrimes