13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===---------------------- condition_variable ----------------------------===//
33e519524SHoward Hinnant//
4*5b08a8a4SHoward Hinnant//                     The LLVM Compiler Infrastructure
53e519524SHoward Hinnant//
63e519524SHoward Hinnant// This file is distributed under the University of Illinois Open Source
73e519524SHoward Hinnant// License. See LICENSE.TXT for details.
83e519524SHoward Hinnant//
93e519524SHoward Hinnant//===----------------------------------------------------------------------===//
103e519524SHoward Hinnant
113e519524SHoward Hinnant#ifndef _LIBCPP_CONDITION_VARIABLE
123e519524SHoward Hinnant#define _LIBCPP_CONDITION_VARIABLE
133e519524SHoward Hinnant
143e519524SHoward Hinnant/*
153e519524SHoward Hinnant    condition_variable synopsis
163e519524SHoward Hinnant
173e519524SHoward Hinnantnamespace std
183e519524SHoward Hinnant{
193e519524SHoward Hinnant
203e519524SHoward Hinnantenum class cv_status { no_timeout, timeout };
213e519524SHoward Hinnant
223e519524SHoward Hinnantclass condition_variable
233e519524SHoward Hinnant{
243e519524SHoward Hinnantpublic:
253e519524SHoward Hinnant    condition_variable();
263e519524SHoward Hinnant    ~condition_variable();
273e519524SHoward Hinnant
283e519524SHoward Hinnant    condition_variable(const condition_variable&) = delete;
293e519524SHoward Hinnant    condition_variable& operator=(const condition_variable&) = delete;
303e519524SHoward Hinnant
313e519524SHoward Hinnant    void notify_one();
323e519524SHoward Hinnant    void notify_all();
333e519524SHoward Hinnant
343e519524SHoward Hinnant    void wait(unique_lock<mutex>& lock);
353e519524SHoward Hinnant    template <class Predicate>
363e519524SHoward Hinnant        void wait(unique_lock<mutex>& lock, Predicate pred);
373e519524SHoward Hinnant
383e519524SHoward Hinnant    template <class Clock, class Duration>
393e519524SHoward Hinnant        cv_status
403e519524SHoward Hinnant        wait_until(unique_lock<mutex>& lock,
413e519524SHoward Hinnant                   const chrono::time_point<Clock, Duration>& abs_time);
423e519524SHoward Hinnant
433e519524SHoward Hinnant    template <class Clock, class Duration, class Predicate>
443e519524SHoward Hinnant        bool
453e519524SHoward Hinnant        wait_until(unique_lock<mutex>& lock,
463e519524SHoward Hinnant                   const chrono::time_point<Clock, Duration>& abs_time,
473e519524SHoward Hinnant                   Predicate pred);
483e519524SHoward Hinnant
493e519524SHoward Hinnant    template <class Rep, class Period>
503e519524SHoward Hinnant        cv_status
513e519524SHoward Hinnant        wait_for(unique_lock<mutex>& lock,
523e519524SHoward Hinnant                 const chrono::duration<Rep, Period>& rel_time);
533e519524SHoward Hinnant
543e519524SHoward Hinnant    template <class Rep, class Period, class Predicate>
553e519524SHoward Hinnant        bool
563e519524SHoward Hinnant        wait_for(unique_lock<mutex>& lock,
573e519524SHoward Hinnant                 const chrono::duration<Rep, Period>& rel_time,
583e519524SHoward Hinnant                 Predicate pred);
593e519524SHoward Hinnant
603e519524SHoward Hinnant    typedef pthread_cond_t* native_handle_type;
613e519524SHoward Hinnant    native_handle_type native_handle();
623e519524SHoward Hinnant};
633e519524SHoward Hinnant
643e519524SHoward Hinnantclass condition_variable_any
653e519524SHoward Hinnant{
663e519524SHoward Hinnantpublic:
673e519524SHoward Hinnant    condition_variable_any();
683e519524SHoward Hinnant    ~condition_variable_any();
693e519524SHoward Hinnant
703e519524SHoward Hinnant    condition_variable_any(const condition_variable_any&) = delete;
713e519524SHoward Hinnant    condition_variable_any& operator=(const condition_variable_any&) = delete;
723e519524SHoward Hinnant
733e519524SHoward Hinnant    void notify_one();
743e519524SHoward Hinnant    void notify_all();
753e519524SHoward Hinnant
763e519524SHoward Hinnant    template <class Lock>
773e519524SHoward Hinnant        void wait(Lock& lock);
783e519524SHoward Hinnant    template <class Lock, class Predicate>
793e519524SHoward Hinnant        void wait(Lock& lock, Predicate pred);
803e519524SHoward Hinnant
813e519524SHoward Hinnant    template <class Lock, class Clock, class Duration>
823e519524SHoward Hinnant        cv_status
833e519524SHoward Hinnant        wait_until(Lock& lock,
843e519524SHoward Hinnant                   const chrono::time_point<Clock, Duration>& abs_time);
853e519524SHoward Hinnant
863e519524SHoward Hinnant    template <class Lock, class Clock, class Duration, class Predicate>
873e519524SHoward Hinnant        bool
883e519524SHoward Hinnant        wait_until(Lock& lock,
893e519524SHoward Hinnant                   const chrono::time_point<Clock, Duration>& abs_time,
903e519524SHoward Hinnant                   Predicate pred);
913e519524SHoward Hinnant
923e519524SHoward Hinnant    template <class Lock, class Rep, class Period>
933e519524SHoward Hinnant        cv_status
943e519524SHoward Hinnant        wait_for(Lock& lock,
953e519524SHoward Hinnant                 const chrono::duration<Rep, Period>& rel_time);
963e519524SHoward Hinnant
973e519524SHoward Hinnant    template <class Lock, class Rep, class Period, class Predicate>
983e519524SHoward Hinnant        bool
993e519524SHoward Hinnant        wait_for(Lock& lock,
1003e519524SHoward Hinnant                 const chrono::duration<Rep, Period>& rel_time,
1013e519524SHoward Hinnant                 Predicate pred);
1023e519524SHoward Hinnant};
1033e519524SHoward Hinnant
1043e519524SHoward Hinnant}  // std
1053e519524SHoward Hinnant
1063e519524SHoward Hinnant*/
1073e519524SHoward Hinnant
1083e519524SHoward Hinnant#include <__config>
1093e519524SHoward Hinnant#include <__mutex_base>
1103e519524SHoward Hinnant#include <memory>
1113e519524SHoward Hinnant
1123e519524SHoward Hinnant#pragma GCC system_header
1133e519524SHoward Hinnant
1143e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
1153e519524SHoward Hinnant
1163e519524SHoward Hinnantclass condition_variable_any
1173e519524SHoward Hinnant{
1183e519524SHoward Hinnant    condition_variable __cv_;
1193e519524SHoward Hinnant    shared_ptr<mutex>  __mut_;
1203e519524SHoward Hinnantpublic:
1213e519524SHoward Hinnant    condition_variable_any();
1223e519524SHoward Hinnant
1233e519524SHoward Hinnant    void notify_one();
1243e519524SHoward Hinnant    void notify_all();
1253e519524SHoward Hinnant
1263e519524SHoward Hinnant    template <class _Lock>
1273e519524SHoward Hinnant        void wait(_Lock& __lock);
1283e519524SHoward Hinnant    template <class _Lock, class _Predicate>
1293e519524SHoward Hinnant        void wait(_Lock& __lock, _Predicate __pred);
1303e519524SHoward Hinnant
1313e519524SHoward Hinnant    template <class _Lock, class _Clock, class _Duration>
1323e519524SHoward Hinnant        cv_status
1333e519524SHoward Hinnant        wait_until(_Lock& __lock,
1343e519524SHoward Hinnant                   const chrono::time_point<_Clock, _Duration>& __t);
1353e519524SHoward Hinnant
1363e519524SHoward Hinnant    template <class _Lock, class _Clock, class _Duration, class _Predicate>
1373e519524SHoward Hinnant        bool
1383e519524SHoward Hinnant        wait_until(_Lock& __lock,
1393e519524SHoward Hinnant                   const chrono::time_point<_Clock, _Duration>& __t,
1403e519524SHoward Hinnant                   _Predicate __pred);
1413e519524SHoward Hinnant
1423e519524SHoward Hinnant    template <class _Lock, class _Rep, class _Period>
1433e519524SHoward Hinnant        cv_status
1443e519524SHoward Hinnant        wait_for(_Lock& __lock,
1453e519524SHoward Hinnant                 const chrono::duration<_Rep, _Period>& __d);
1463e519524SHoward Hinnant
1473e519524SHoward Hinnant    template <class _Lock, class _Rep, class _Period, class _Predicate>
1483e519524SHoward Hinnant        bool
1493e519524SHoward Hinnant        wait_for(_Lock& __lock,
1503e519524SHoward Hinnant                 const chrono::duration<_Rep, _Period>& __d,
1513e519524SHoward Hinnant                 _Predicate __pred);
1523e519524SHoward Hinnant};
1533e519524SHoward Hinnant
1543e519524SHoward Hinnantinline
1553e519524SHoward Hinnantcondition_variable_any::condition_variable_any()
1563e519524SHoward Hinnant    : __mut_(make_shared<mutex>()) {}
1573e519524SHoward Hinnant
1583e519524SHoward Hinnantinline
1593e519524SHoward Hinnantvoid
1603e519524SHoward Hinnantcondition_variable_any::notify_one()
1613e519524SHoward Hinnant{
1623e519524SHoward Hinnant    {lock_guard<mutex> _(*__mut_);}
1633e519524SHoward Hinnant    __cv_.notify_one();
1643e519524SHoward Hinnant}
1653e519524SHoward Hinnant
1663e519524SHoward Hinnantinline
1673e519524SHoward Hinnantvoid
1683e519524SHoward Hinnantcondition_variable_any::notify_all()
1693e519524SHoward Hinnant{
1703e519524SHoward Hinnant    {lock_guard<mutex> _(*__mut_);}
1713e519524SHoward Hinnant    __cv_.notify_all();
1723e519524SHoward Hinnant}
1733e519524SHoward Hinnant
1743e519524SHoward Hinnantstruct __lock_external
1753e519524SHoward Hinnant{
1763e519524SHoward Hinnant    template <class _Lock>
1773e519524SHoward Hinnant    void operator()(_Lock* __m) {__m->lock();}
1783e519524SHoward Hinnant};
1793e519524SHoward Hinnant
1803e519524SHoward Hinnanttemplate <class _Lock>
1813e519524SHoward Hinnantvoid
1823e519524SHoward Hinnantcondition_variable_any::wait(_Lock& __lock)
1833e519524SHoward Hinnant{
1843e519524SHoward Hinnant    shared_ptr<mutex> __mut = __mut_;
1853e519524SHoward Hinnant    unique_lock<mutex> __lk(*__mut);
1863e519524SHoward Hinnant    __lock.unlock();
1873e519524SHoward Hinnant    unique_ptr<_Lock, __lock_external> __(&__lock);
1883e519524SHoward Hinnant    lock_guard<unique_lock<mutex> > _(__lk, adopt_lock);
1893e519524SHoward Hinnant    __cv_.wait(__lk);
1903e519524SHoward Hinnant}  // __mut_.unlock(), __lock.lock()
1913e519524SHoward Hinnant
1923e519524SHoward Hinnanttemplate <class _Lock, class _Predicate>
1933e519524SHoward Hinnantinline
1943e519524SHoward Hinnantvoid
1953e519524SHoward Hinnantcondition_variable_any::wait(_Lock& __lock, _Predicate __pred)
1963e519524SHoward Hinnant{
1973e519524SHoward Hinnant    while (!__pred())
1983e519524SHoward Hinnant        wait(__lock);
1993e519524SHoward Hinnant}
2003e519524SHoward Hinnant
2013e519524SHoward Hinnanttemplate <class _Lock, class _Clock, class _Duration>
2023e519524SHoward Hinnantcv_status
2033e519524SHoward Hinnantcondition_variable_any::wait_until(_Lock& __lock,
2043e519524SHoward Hinnant                                   const chrono::time_point<_Clock, _Duration>& __t)
2053e519524SHoward Hinnant{
2063e519524SHoward Hinnant    shared_ptr<mutex> __mut = __mut_;
2073e519524SHoward Hinnant    unique_lock<mutex> __lk(*__mut);
2083e519524SHoward Hinnant    __lock.unlock();
2093e519524SHoward Hinnant    unique_ptr<_Lock, __lock_external> __(&__lock);
2103e519524SHoward Hinnant    lock_guard<unique_lock<mutex> > _(__lk, adopt_lock);
2113e519524SHoward Hinnant    return __cv_.wait_until(__lk, __t);
2123e519524SHoward Hinnant}  // __mut_.unlock(), __lock.lock()
2133e519524SHoward Hinnant
2143e519524SHoward Hinnanttemplate <class _Lock, class _Clock, class _Duration, class _Predicate>
2153e519524SHoward Hinnantinline
2163e519524SHoward Hinnantbool
2173e519524SHoward Hinnantcondition_variable_any::wait_until(_Lock& __lock,
2183e519524SHoward Hinnant                                   const chrono::time_point<_Clock, _Duration>& __t,
2193e519524SHoward Hinnant                                   _Predicate __pred)
2203e519524SHoward Hinnant{
2213e519524SHoward Hinnant    while (!__pred())
2223e519524SHoward Hinnant        if (wait_until(__lock, __t) == cv_status::timeout)
2233e519524SHoward Hinnant            return __pred();
2243e519524SHoward Hinnant    return true;
2253e519524SHoward Hinnant}
2263e519524SHoward Hinnant
2273e519524SHoward Hinnanttemplate <class _Lock, class _Rep, class _Period>
2283e519524SHoward Hinnantinline
2293e519524SHoward Hinnantcv_status
2303e519524SHoward Hinnantcondition_variable_any::wait_for(_Lock& __lock,
2313e519524SHoward Hinnant                                 const chrono::duration<_Rep, _Period>& __d)
2323e519524SHoward Hinnant{
2333e519524SHoward Hinnant    return wait_until(__lock, chrono::monotonic_clock::now() + __d);
2343e519524SHoward Hinnant}
2353e519524SHoward Hinnant
2363e519524SHoward Hinnanttemplate <class _Lock, class _Rep, class _Period, class _Predicate>
2373e519524SHoward Hinnantinline
2383e519524SHoward Hinnantbool
2393e519524SHoward Hinnantcondition_variable_any::wait_for(_Lock& __lock,
2403e519524SHoward Hinnant                                 const chrono::duration<_Rep, _Period>& __d,
2413e519524SHoward Hinnant                                 _Predicate __pred)
2423e519524SHoward Hinnant{
2433e519524SHoward Hinnant    return wait_until(__lock, chrono::monotonic_clock::now() + __d,
2443e519524SHoward Hinnant                      _STD::move(__pred));
2453e519524SHoward Hinnant}
2463e519524SHoward Hinnant
2473e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
2483e519524SHoward Hinnant
2493e519524SHoward Hinnant#endif  // _LIBCPP_CONDITION_VARIABLE
250