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