14684ddb6SLionel Sambuc// -*- C++ -*- 24684ddb6SLionel Sambuc//===---------------------- condition_variable ----------------------------===// 34684ddb6SLionel Sambuc// 44684ddb6SLionel Sambuc// The LLVM Compiler Infrastructure 54684ddb6SLionel Sambuc// 64684ddb6SLionel Sambuc// This file is dual licensed under the MIT and the University of Illinois Open 74684ddb6SLionel Sambuc// Source Licenses. See LICENSE.TXT for details. 84684ddb6SLionel Sambuc// 94684ddb6SLionel Sambuc//===----------------------------------------------------------------------===// 104684ddb6SLionel Sambuc 114684ddb6SLionel Sambuc#ifndef _LIBCPP_CONDITION_VARIABLE 124684ddb6SLionel Sambuc#define _LIBCPP_CONDITION_VARIABLE 134684ddb6SLionel Sambuc 144684ddb6SLionel Sambuc/* 154684ddb6SLionel Sambuc condition_variable synopsis 164684ddb6SLionel Sambuc 174684ddb6SLionel Sambucnamespace std 184684ddb6SLionel Sambuc{ 194684ddb6SLionel Sambuc 204684ddb6SLionel Sambucenum class cv_status { no_timeout, timeout }; 214684ddb6SLionel Sambuc 224684ddb6SLionel Sambucclass condition_variable 234684ddb6SLionel Sambuc{ 244684ddb6SLionel Sambucpublic: 254684ddb6SLionel Sambuc condition_variable(); 264684ddb6SLionel Sambuc ~condition_variable(); 274684ddb6SLionel Sambuc 284684ddb6SLionel Sambuc condition_variable(const condition_variable&) = delete; 294684ddb6SLionel Sambuc condition_variable& operator=(const condition_variable&) = delete; 304684ddb6SLionel Sambuc 314684ddb6SLionel Sambuc void notify_one() noexcept; 324684ddb6SLionel Sambuc void notify_all() noexcept; 334684ddb6SLionel Sambuc 344684ddb6SLionel Sambuc void wait(unique_lock<mutex>& lock); 354684ddb6SLionel Sambuc template <class Predicate> 364684ddb6SLionel Sambuc void wait(unique_lock<mutex>& lock, Predicate pred); 374684ddb6SLionel Sambuc 384684ddb6SLionel Sambuc template <class Clock, class Duration> 394684ddb6SLionel Sambuc cv_status 404684ddb6SLionel Sambuc wait_until(unique_lock<mutex>& lock, 414684ddb6SLionel Sambuc const chrono::time_point<Clock, Duration>& abs_time); 424684ddb6SLionel Sambuc 434684ddb6SLionel Sambuc template <class Clock, class Duration, class Predicate> 444684ddb6SLionel Sambuc bool 454684ddb6SLionel Sambuc wait_until(unique_lock<mutex>& lock, 464684ddb6SLionel Sambuc const chrono::time_point<Clock, Duration>& abs_time, 474684ddb6SLionel Sambuc Predicate pred); 484684ddb6SLionel Sambuc 494684ddb6SLionel Sambuc template <class Rep, class Period> 504684ddb6SLionel Sambuc cv_status 514684ddb6SLionel Sambuc wait_for(unique_lock<mutex>& lock, 524684ddb6SLionel Sambuc const chrono::duration<Rep, Period>& rel_time); 534684ddb6SLionel Sambuc 544684ddb6SLionel Sambuc template <class Rep, class Period, class Predicate> 554684ddb6SLionel Sambuc bool 564684ddb6SLionel Sambuc wait_for(unique_lock<mutex>& lock, 574684ddb6SLionel Sambuc const chrono::duration<Rep, Period>& rel_time, 584684ddb6SLionel Sambuc Predicate pred); 594684ddb6SLionel Sambuc 604684ddb6SLionel Sambuc typedef pthread_cond_t* native_handle_type; 614684ddb6SLionel Sambuc native_handle_type native_handle(); 624684ddb6SLionel Sambuc}; 634684ddb6SLionel Sambuc 644684ddb6SLionel Sambucvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 654684ddb6SLionel Sambuc 664684ddb6SLionel Sambucclass condition_variable_any 674684ddb6SLionel Sambuc{ 684684ddb6SLionel Sambucpublic: 694684ddb6SLionel Sambuc condition_variable_any(); 704684ddb6SLionel Sambuc ~condition_variable_any(); 714684ddb6SLionel Sambuc 724684ddb6SLionel Sambuc condition_variable_any(const condition_variable_any&) = delete; 734684ddb6SLionel Sambuc condition_variable_any& operator=(const condition_variable_any&) = delete; 744684ddb6SLionel Sambuc 754684ddb6SLionel Sambuc void notify_one() noexcept; 764684ddb6SLionel Sambuc void notify_all() noexcept; 774684ddb6SLionel Sambuc 784684ddb6SLionel Sambuc template <class Lock> 794684ddb6SLionel Sambuc void wait(Lock& lock); 804684ddb6SLionel Sambuc template <class Lock, class Predicate> 814684ddb6SLionel Sambuc void wait(Lock& lock, Predicate pred); 824684ddb6SLionel Sambuc 834684ddb6SLionel Sambuc template <class Lock, class Clock, class Duration> 844684ddb6SLionel Sambuc cv_status 854684ddb6SLionel Sambuc wait_until(Lock& lock, 864684ddb6SLionel Sambuc const chrono::time_point<Clock, Duration>& abs_time); 874684ddb6SLionel Sambuc 884684ddb6SLionel Sambuc template <class Lock, class Clock, class Duration, class Predicate> 894684ddb6SLionel Sambuc bool 904684ddb6SLionel Sambuc wait_until(Lock& lock, 914684ddb6SLionel Sambuc const chrono::time_point<Clock, Duration>& abs_time, 924684ddb6SLionel Sambuc Predicate pred); 934684ddb6SLionel Sambuc 944684ddb6SLionel Sambuc template <class Lock, class Rep, class Period> 954684ddb6SLionel Sambuc cv_status 964684ddb6SLionel Sambuc wait_for(Lock& lock, 974684ddb6SLionel Sambuc const chrono::duration<Rep, Period>& rel_time); 984684ddb6SLionel Sambuc 994684ddb6SLionel Sambuc template <class Lock, class Rep, class Period, class Predicate> 1004684ddb6SLionel Sambuc bool 1014684ddb6SLionel Sambuc wait_for(Lock& lock, 1024684ddb6SLionel Sambuc const chrono::duration<Rep, Period>& rel_time, 1034684ddb6SLionel Sambuc Predicate pred); 1044684ddb6SLionel Sambuc}; 1054684ddb6SLionel Sambuc 1064684ddb6SLionel Sambuc} // std 1074684ddb6SLionel Sambuc 1084684ddb6SLionel Sambuc*/ 1094684ddb6SLionel Sambuc 1104684ddb6SLionel Sambuc#include <__config> 1114684ddb6SLionel Sambuc#include <__mutex_base> 1124684ddb6SLionel Sambuc#include <memory> 1134684ddb6SLionel Sambuc 1144684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1154684ddb6SLionel Sambuc#pragma GCC system_header 1164684ddb6SLionel Sambuc#endif 1174684ddb6SLionel Sambuc 118*0a6a1f1dSLionel Sambuc#ifndef _LIBCPP_HAS_NO_THREADS 119*0a6a1f1dSLionel Sambuc 1204684ddb6SLionel Sambuc_LIBCPP_BEGIN_NAMESPACE_STD 1214684ddb6SLionel Sambuc 1224684ddb6SLionel Sambucclass _LIBCPP_TYPE_VIS condition_variable_any 1234684ddb6SLionel Sambuc{ 1244684ddb6SLionel Sambuc condition_variable __cv_; 1254684ddb6SLionel Sambuc shared_ptr<mutex> __mut_; 1264684ddb6SLionel Sambucpublic: 1274684ddb6SLionel Sambuc condition_variable_any(); 1284684ddb6SLionel Sambuc 1294684ddb6SLionel Sambuc void notify_one() _NOEXCEPT; 1304684ddb6SLionel Sambuc void notify_all() _NOEXCEPT; 1314684ddb6SLionel Sambuc 1324684ddb6SLionel Sambuc template <class _Lock> 1334684ddb6SLionel Sambuc void wait(_Lock& __lock); 1344684ddb6SLionel Sambuc template <class _Lock, class _Predicate> 1354684ddb6SLionel Sambuc void wait(_Lock& __lock, _Predicate __pred); 1364684ddb6SLionel Sambuc 1374684ddb6SLionel Sambuc template <class _Lock, class _Clock, class _Duration> 1384684ddb6SLionel Sambuc cv_status 1394684ddb6SLionel Sambuc wait_until(_Lock& __lock, 1404684ddb6SLionel Sambuc const chrono::time_point<_Clock, _Duration>& __t); 1414684ddb6SLionel Sambuc 1424684ddb6SLionel Sambuc template <class _Lock, class _Clock, class _Duration, class _Predicate> 1434684ddb6SLionel Sambuc bool 1444684ddb6SLionel Sambuc wait_until(_Lock& __lock, 1454684ddb6SLionel Sambuc const chrono::time_point<_Clock, _Duration>& __t, 1464684ddb6SLionel Sambuc _Predicate __pred); 1474684ddb6SLionel Sambuc 1484684ddb6SLionel Sambuc template <class _Lock, class _Rep, class _Period> 1494684ddb6SLionel Sambuc cv_status 1504684ddb6SLionel Sambuc wait_for(_Lock& __lock, 1514684ddb6SLionel Sambuc const chrono::duration<_Rep, _Period>& __d); 1524684ddb6SLionel Sambuc 1534684ddb6SLionel Sambuc template <class _Lock, class _Rep, class _Period, class _Predicate> 1544684ddb6SLionel Sambuc bool 1554684ddb6SLionel Sambuc wait_for(_Lock& __lock, 1564684ddb6SLionel Sambuc const chrono::duration<_Rep, _Period>& __d, 1574684ddb6SLionel Sambuc _Predicate __pred); 1584684ddb6SLionel Sambuc}; 1594684ddb6SLionel Sambuc 1604684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 1614684ddb6SLionel Sambuccondition_variable_any::condition_variable_any() 1624684ddb6SLionel Sambuc : __mut_(make_shared<mutex>()) {} 1634684ddb6SLionel Sambuc 1644684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 1654684ddb6SLionel Sambucvoid 1664684ddb6SLionel Sambuccondition_variable_any::notify_one() _NOEXCEPT 1674684ddb6SLionel Sambuc{ 1684684ddb6SLionel Sambuc {lock_guard<mutex> __lx(*__mut_);} 1694684ddb6SLionel Sambuc __cv_.notify_one(); 1704684ddb6SLionel Sambuc} 1714684ddb6SLionel Sambuc 1724684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 1734684ddb6SLionel Sambucvoid 1744684ddb6SLionel Sambuccondition_variable_any::notify_all() _NOEXCEPT 1754684ddb6SLionel Sambuc{ 1764684ddb6SLionel Sambuc {lock_guard<mutex> __lx(*__mut_);} 1774684ddb6SLionel Sambuc __cv_.notify_all(); 1784684ddb6SLionel Sambuc} 1794684ddb6SLionel Sambuc 1804684ddb6SLionel Sambucstruct __lock_external 1814684ddb6SLionel Sambuc{ 1824684ddb6SLionel Sambuc template <class _Lock> 1834684ddb6SLionel Sambuc void operator()(_Lock* __m) {__m->lock();} 1844684ddb6SLionel Sambuc}; 1854684ddb6SLionel Sambuc 1864684ddb6SLionel Sambuctemplate <class _Lock> 1874684ddb6SLionel Sambucvoid 1884684ddb6SLionel Sambuccondition_variable_any::wait(_Lock& __lock) 1894684ddb6SLionel Sambuc{ 1904684ddb6SLionel Sambuc shared_ptr<mutex> __mut = __mut_; 1914684ddb6SLionel Sambuc unique_lock<mutex> __lk(*__mut); 1924684ddb6SLionel Sambuc __lock.unlock(); 1934684ddb6SLionel Sambuc unique_ptr<_Lock, __lock_external> __lxx(&__lock); 1944684ddb6SLionel Sambuc lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 1954684ddb6SLionel Sambuc __cv_.wait(__lk); 1964684ddb6SLionel Sambuc} // __mut_.unlock(), __lock.lock() 1974684ddb6SLionel Sambuc 1984684ddb6SLionel Sambuctemplate <class _Lock, class _Predicate> 1994684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 2004684ddb6SLionel Sambucvoid 2014684ddb6SLionel Sambuccondition_variable_any::wait(_Lock& __lock, _Predicate __pred) 2024684ddb6SLionel Sambuc{ 2034684ddb6SLionel Sambuc while (!__pred()) 2044684ddb6SLionel Sambuc wait(__lock); 2054684ddb6SLionel Sambuc} 2064684ddb6SLionel Sambuc 2074684ddb6SLionel Sambuctemplate <class _Lock, class _Clock, class _Duration> 2084684ddb6SLionel Sambuccv_status 2094684ddb6SLionel Sambuccondition_variable_any::wait_until(_Lock& __lock, 2104684ddb6SLionel Sambuc const chrono::time_point<_Clock, _Duration>& __t) 2114684ddb6SLionel Sambuc{ 2124684ddb6SLionel Sambuc shared_ptr<mutex> __mut = __mut_; 2134684ddb6SLionel Sambuc unique_lock<mutex> __lk(*__mut); 2144684ddb6SLionel Sambuc __lock.unlock(); 2154684ddb6SLionel Sambuc unique_ptr<_Lock, __lock_external> __lxx(&__lock); 2164684ddb6SLionel Sambuc lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); 2174684ddb6SLionel Sambuc return __cv_.wait_until(__lk, __t); 2184684ddb6SLionel Sambuc} // __mut_.unlock(), __lock.lock() 2194684ddb6SLionel Sambuc 2204684ddb6SLionel Sambuctemplate <class _Lock, class _Clock, class _Duration, class _Predicate> 2214684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 2224684ddb6SLionel Sambucbool 2234684ddb6SLionel Sambuccondition_variable_any::wait_until(_Lock& __lock, 2244684ddb6SLionel Sambuc const chrono::time_point<_Clock, _Duration>& __t, 2254684ddb6SLionel Sambuc _Predicate __pred) 2264684ddb6SLionel Sambuc{ 2274684ddb6SLionel Sambuc while (!__pred()) 2284684ddb6SLionel Sambuc if (wait_until(__lock, __t) == cv_status::timeout) 2294684ddb6SLionel Sambuc return __pred(); 2304684ddb6SLionel Sambuc return true; 2314684ddb6SLionel Sambuc} 2324684ddb6SLionel Sambuc 2334684ddb6SLionel Sambuctemplate <class _Lock, class _Rep, class _Period> 2344684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 2354684ddb6SLionel Sambuccv_status 2364684ddb6SLionel Sambuccondition_variable_any::wait_for(_Lock& __lock, 2374684ddb6SLionel Sambuc const chrono::duration<_Rep, _Period>& __d) 2384684ddb6SLionel Sambuc{ 2394684ddb6SLionel Sambuc return wait_until(__lock, chrono::steady_clock::now() + __d); 2404684ddb6SLionel Sambuc} 2414684ddb6SLionel Sambuc 2424684ddb6SLionel Sambuctemplate <class _Lock, class _Rep, class _Period, class _Predicate> 2434684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY 2444684ddb6SLionel Sambucbool 2454684ddb6SLionel Sambuccondition_variable_any::wait_for(_Lock& __lock, 2464684ddb6SLionel Sambuc const chrono::duration<_Rep, _Period>& __d, 2474684ddb6SLionel Sambuc _Predicate __pred) 2484684ddb6SLionel Sambuc{ 2494684ddb6SLionel Sambuc return wait_until(__lock, chrono::steady_clock::now() + __d, 2504684ddb6SLionel Sambuc _VSTD::move(__pred)); 2514684ddb6SLionel Sambuc} 2524684ddb6SLionel Sambuc 2534684ddb6SLionel Sambuc_LIBCPP_FUNC_VIS 2544684ddb6SLionel Sambucvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); 2554684ddb6SLionel Sambuc 2564684ddb6SLionel Sambuc_LIBCPP_END_NAMESPACE_STD 2574684ddb6SLionel Sambuc 258*0a6a1f1dSLionel Sambuc#endif // !_LIBCPP_HAS_NO_THREADS 259*0a6a1f1dSLionel Sambuc 2604684ddb6SLionel Sambuc#endif // _LIBCPP_CONDITION_VARIABLE 261