condition_variable revision 242945
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===---------------------- condition_variable ----------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_CONDITION_VARIABLE
12227825Stheraven#define _LIBCPP_CONDITION_VARIABLE
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    condition_variable synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheravenenum class cv_status { no_timeout, timeout };
21227825Stheraven
22227825Stheravenclass condition_variable
23227825Stheraven{
24227825Stheravenpublic:
25227825Stheraven    condition_variable();
26227825Stheraven    ~condition_variable();
27227825Stheraven
28227825Stheraven    condition_variable(const condition_variable&) = delete;
29227825Stheraven    condition_variable& operator=(const condition_variable&) = delete;
30227825Stheraven
31241903Sdim    void notify_one() noexcept;
32241903Sdim    void notify_all() noexcept;
33227825Stheraven
34227825Stheraven    void wait(unique_lock<mutex>& lock);
35227825Stheraven    template <class Predicate>
36227825Stheraven        void wait(unique_lock<mutex>& lock, Predicate pred);
37227825Stheraven
38227825Stheraven    template <class Clock, class Duration>
39227825Stheraven        cv_status
40227825Stheraven        wait_until(unique_lock<mutex>& lock,
41227825Stheraven                   const chrono::time_point<Clock, Duration>& abs_time);
42227825Stheraven
43227825Stheraven    template <class Clock, class Duration, class Predicate>
44227825Stheraven        bool
45227825Stheraven        wait_until(unique_lock<mutex>& lock,
46227825Stheraven                   const chrono::time_point<Clock, Duration>& abs_time,
47227825Stheraven                   Predicate pred);
48227825Stheraven
49227825Stheraven    template <class Rep, class Period>
50227825Stheraven        cv_status
51227825Stheraven        wait_for(unique_lock<mutex>& lock,
52227825Stheraven                 const chrono::duration<Rep, Period>& rel_time);
53227825Stheraven
54227825Stheraven    template <class Rep, class Period, class Predicate>
55227825Stheraven        bool
56227825Stheraven        wait_for(unique_lock<mutex>& lock,
57227825Stheraven                 const chrono::duration<Rep, Period>& rel_time,
58227825Stheraven                 Predicate pred);
59227825Stheraven
60227825Stheraven    typedef pthread_cond_t* native_handle_type;
61227825Stheraven    native_handle_type native_handle();
62227825Stheraven};
63227825Stheraven
64227825Stheravenvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
65227825Stheraven
66227825Stheravenclass condition_variable_any
67227825Stheraven{
68227825Stheravenpublic:
69227825Stheraven    condition_variable_any();
70227825Stheraven    ~condition_variable_any();
71227825Stheraven
72227825Stheraven    condition_variable_any(const condition_variable_any&) = delete;
73227825Stheraven    condition_variable_any& operator=(const condition_variable_any&) = delete;
74227825Stheraven
75241903Sdim    void notify_one() noexcept;
76241903Sdim    void notify_all() noexcept;
77227825Stheraven
78227825Stheraven    template <class Lock>
79227825Stheraven        void wait(Lock& lock);
80227825Stheraven    template <class Lock, class Predicate>
81227825Stheraven        void wait(Lock& lock, Predicate pred);
82227825Stheraven
83227825Stheraven    template <class Lock, class Clock, class Duration>
84227825Stheraven        cv_status
85227825Stheraven        wait_until(Lock& lock,
86227825Stheraven                   const chrono::time_point<Clock, Duration>& abs_time);
87227825Stheraven
88227825Stheraven    template <class Lock, class Clock, class Duration, class Predicate>
89227825Stheraven        bool
90227825Stheraven        wait_until(Lock& lock,
91227825Stheraven                   const chrono::time_point<Clock, Duration>& abs_time,
92227825Stheraven                   Predicate pred);
93227825Stheraven
94227825Stheraven    template <class Lock, class Rep, class Period>
95227825Stheraven        cv_status
96227825Stheraven        wait_for(Lock& lock,
97227825Stheraven                 const chrono::duration<Rep, Period>& rel_time);
98227825Stheraven
99227825Stheraven    template <class Lock, class Rep, class Period, class Predicate>
100227825Stheraven        bool
101227825Stheraven        wait_for(Lock& lock,
102227825Stheraven                 const chrono::duration<Rep, Period>& rel_time,
103227825Stheraven                 Predicate pred);
104227825Stheraven};
105227825Stheraven
106227825Stheraven}  // std
107227825Stheraven
108227825Stheraven*/
109227825Stheraven
110227825Stheraven#include <__config>
111227825Stheraven#include <__mutex_base>
112227825Stheraven#include <memory>
113227825Stheraven
114227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
115227825Stheraven#pragma GCC system_header
116227825Stheraven#endif
117227825Stheraven
118227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
119227825Stheraven
120227825Stheravenclass _LIBCPP_VISIBLE condition_variable_any
121227825Stheraven{
122227825Stheraven    condition_variable __cv_;
123227825Stheraven    shared_ptr<mutex>  __mut_;
124227825Stheravenpublic:
125227825Stheraven    condition_variable_any();
126227825Stheraven
127241903Sdim    void notify_one() _NOEXCEPT;
128241903Sdim    void notify_all() _NOEXCEPT;
129227825Stheraven
130227825Stheraven    template <class _Lock>
131227825Stheraven        void wait(_Lock& __lock);
132227825Stheraven    template <class _Lock, class _Predicate>
133227825Stheraven        void wait(_Lock& __lock, _Predicate __pred);
134227825Stheraven
135227825Stheraven    template <class _Lock, class _Clock, class _Duration>
136227825Stheraven        cv_status
137227825Stheraven        wait_until(_Lock& __lock,
138227825Stheraven                   const chrono::time_point<_Clock, _Duration>& __t);
139227825Stheraven
140227825Stheraven    template <class _Lock, class _Clock, class _Duration, class _Predicate>
141227825Stheraven        bool
142227825Stheraven        wait_until(_Lock& __lock,
143227825Stheraven                   const chrono::time_point<_Clock, _Duration>& __t,
144227825Stheraven                   _Predicate __pred);
145227825Stheraven
146227825Stheraven    template <class _Lock, class _Rep, class _Period>
147227825Stheraven        cv_status
148227825Stheraven        wait_for(_Lock& __lock,
149227825Stheraven                 const chrono::duration<_Rep, _Period>& __d);
150227825Stheraven
151227825Stheraven    template <class _Lock, class _Rep, class _Period, class _Predicate>
152227825Stheraven        bool
153227825Stheraven        wait_for(_Lock& __lock,
154227825Stheraven                 const chrono::duration<_Rep, _Period>& __d,
155227825Stheraven                 _Predicate __pred);
156227825Stheraven};
157227825Stheraven
158227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
159227825Stheravencondition_variable_any::condition_variable_any()
160227825Stheraven    : __mut_(make_shared<mutex>()) {}
161227825Stheraven
162227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
163227825Stheravenvoid
164241903Sdimcondition_variable_any::notify_one() _NOEXCEPT
165227825Stheraven{
166242945Stheraven    {lock_guard<mutex> __lx(*__mut_);}
167227825Stheraven    __cv_.notify_one();
168227825Stheraven}
169227825Stheraven
170227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
171227825Stheravenvoid
172241903Sdimcondition_variable_any::notify_all() _NOEXCEPT
173227825Stheraven{
174242945Stheraven    {lock_guard<mutex> __lx(*__mut_);}
175227825Stheraven    __cv_.notify_all();
176227825Stheraven}
177227825Stheraven
178227825Stheravenstruct __lock_external
179227825Stheraven{
180227825Stheraven    template <class _Lock>
181227825Stheraven    void operator()(_Lock* __m) {__m->lock();}
182227825Stheraven};
183227825Stheraven
184227825Stheraventemplate <class _Lock>
185227825Stheravenvoid
186227825Stheravencondition_variable_any::wait(_Lock& __lock)
187227825Stheraven{
188227825Stheraven    shared_ptr<mutex> __mut = __mut_;
189227825Stheraven    unique_lock<mutex> __lk(*__mut);
190227825Stheraven    __lock.unlock();
191242945Stheraven    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
192242945Stheraven    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
193227825Stheraven    __cv_.wait(__lk);
194227825Stheraven}  // __mut_.unlock(), __lock.lock()
195227825Stheraven
196227825Stheraventemplate <class _Lock, class _Predicate>
197227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
198227825Stheravenvoid
199227825Stheravencondition_variable_any::wait(_Lock& __lock, _Predicate __pred)
200227825Stheraven{
201227825Stheraven    while (!__pred())
202227825Stheraven        wait(__lock);
203227825Stheraven}
204227825Stheraven
205227825Stheraventemplate <class _Lock, class _Clock, class _Duration>
206227825Stheravencv_status
207227825Stheravencondition_variable_any::wait_until(_Lock& __lock,
208227825Stheraven                                   const chrono::time_point<_Clock, _Duration>& __t)
209227825Stheraven{
210227825Stheraven    shared_ptr<mutex> __mut = __mut_;
211227825Stheraven    unique_lock<mutex> __lk(*__mut);
212227825Stheraven    __lock.unlock();
213242945Stheraven    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
214242945Stheraven    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
215227825Stheraven    return __cv_.wait_until(__lk, __t);
216227825Stheraven}  // __mut_.unlock(), __lock.lock()
217227825Stheraven
218227825Stheraventemplate <class _Lock, class _Clock, class _Duration, class _Predicate>
219227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
220227825Stheravenbool
221227825Stheravencondition_variable_any::wait_until(_Lock& __lock,
222227825Stheraven                                   const chrono::time_point<_Clock, _Duration>& __t,
223227825Stheraven                                   _Predicate __pred)
224227825Stheraven{
225227825Stheraven    while (!__pred())
226227825Stheraven        if (wait_until(__lock, __t) == cv_status::timeout)
227227825Stheraven            return __pred();
228227825Stheraven    return true;
229227825Stheraven}
230227825Stheraven
231227825Stheraventemplate <class _Lock, class _Rep, class _Period>
232227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
233227825Stheravencv_status
234227825Stheravencondition_variable_any::wait_for(_Lock& __lock,
235227825Stheraven                                 const chrono::duration<_Rep, _Period>& __d)
236227825Stheraven{
237227825Stheraven    return wait_until(__lock, chrono::steady_clock::now() + __d);
238227825Stheraven}
239227825Stheraven
240227825Stheraventemplate <class _Lock, class _Rep, class _Period, class _Predicate>
241227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
242227825Stheravenbool
243227825Stheravencondition_variable_any::wait_for(_Lock& __lock,
244227825Stheraven                                 const chrono::duration<_Rep, _Period>& __d,
245227825Stheraven                                 _Predicate __pred)
246227825Stheraven{
247227825Stheraven    return wait_until(__lock, chrono::steady_clock::now() + __d,
248227825Stheraven                      _VSTD::move(__pred));
249227825Stheraven}
250227825Stheraven
251227825Stheraven_LIBCPP_VISIBLE
252227825Stheravenvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
253227825Stheraven
254227825Stheraven_LIBCPP_END_NAMESPACE_STD
255227825Stheraven
256227825Stheraven#endif  // _LIBCPP_CONDITION_VARIABLE
257