29 #ifndef _GLIBCXX_CONDITION_VARIABLE
30 #define _GLIBCXX_CONDITION_VARIABLE 1
32 #pragma GCC system_header
34 #if __cplusplus < 201103L
46 #include <bits/shared_ptr.h>
49 #if __cplusplus > 201703L
53 #if defined(_GLIBCXX_HAS_GTHREADS)
55 namespace std _GLIBCXX_VISIBILITY(default)
57 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 using steady_clock = chrono::steady_clock;
74 using system_clock = chrono::system_clock;
75 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
76 using __clock_t = steady_clock;
78 using __clock_t = system_clock;
80 typedef __gthread_cond_t __native_type;
82 #ifdef __GTHREAD_COND_INIT
83 __native_type _M_cond = __GTHREAD_COND_INIT;
85 __native_type _M_cond;
89 typedef __native_type* native_handle_type;
98 notify_one() noexcept;
101 notify_all() noexcept;
106 template<
typename _Predicate>
114 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
115 template<
typename _Duration>
119 {
return __wait_until_impl(__lock, __atime); }
122 template<
typename _Duration>
126 {
return __wait_until_impl(__lock, __atime); }
128 template<
typename _Clock,
typename _Duration>
133 #if __cplusplus > 201703L
134 static_assert(chrono::is_clock_v<_Clock>);
136 const typename _Clock::time_point __c_entry = _Clock::now();
137 const __clock_t::time_point __s_entry = __clock_t::now();
138 const auto __delta = __atime - __c_entry;
139 const auto __s_atime = __s_entry + __delta;
141 if (__wait_until_impl(__lock, __s_atime) == cv_status::no_timeout)
142 return cv_status::no_timeout;
146 if (_Clock::now() < __atime)
147 return cv_status::no_timeout;
148 return cv_status::timeout;
151 template<
typename _Clock,
typename _Duration,
typename _Predicate>
158 if (wait_until(__lock, __atime) == cv_status::timeout)
163 template<
typename _Rep,
typename _Period>
168 using __dur =
typename steady_clock::duration;
170 if (__reltime < __rtime)
172 return wait_until(__lock, steady_clock::now() + __reltime);
175 template<
typename _Rep,
typename _Period,
typename _Predicate>
181 using __dur =
typename steady_clock::duration;
183 if (__reltime < __rtime)
185 return wait_until(__lock, steady_clock::now() + __reltime,
194 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
195 template<
typename _Dur>
203 __gthread_time_t __ts =
205 static_cast<std::time_t
>(__s.time_since_epoch().count()),
206 static_cast<long>(__ns.count())
209 pthread_cond_clockwait(&_M_cond, __lock.mutex()->native_handle(),
213 return (steady_clock::now() < __atime
214 ? cv_status::no_timeout : cv_status::timeout);
218 template<
typename _Dur>
226 __gthread_time_t __ts =
228 static_cast<std::time_t
>(__s.time_since_epoch().count()),
229 static_cast<long>(__ns.count())
232 __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
235 return (system_clock::now() < __atime
236 ? cv_status::no_timeout : cv_status::timeout);
243 struct __at_thread_exit_elt
245 __at_thread_exit_elt* _M_next;
246 void (*_M_cb)(
void*);
249 inline namespace _V2 {
255 #ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
256 using __clock_t = chrono::steady_clock;
258 using __clock_t = chrono::system_clock;
264 template<
typename _Lock>
267 explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); }
269 ~_Unlock() noexcept(
false)
276 { __throw_exception_again; }
284 _Unlock(
const _Unlock&) =
delete;
285 _Unlock& operator=(
const _Unlock&) =
delete;
298 notify_one() noexcept
301 _M_cond.notify_one();
305 notify_all() noexcept
308 _M_cond.notify_all();
311 template<
typename _Lock>
317 _Unlock<_Lock> __unlock(__lock);
321 _M_cond.wait(__my_lock2);
325 template<
typename _Lock,
typename _Predicate>
327 wait(_Lock& __lock, _Predicate __p)
333 template<
typename _Lock,
typename _Clock,
typename _Duration>
335 wait_until(_Lock& __lock,
340 _Unlock<_Lock> __unlock(__lock);
344 return _M_cond.wait_until(__my_lock2, __atime);
347 template<
typename _Lock,
typename _Clock,
348 typename _Duration,
typename _Predicate>
350 wait_until(_Lock& __lock,
355 if (wait_until(__lock, __atime) == cv_status::timeout)
360 template<
typename _Lock,
typename _Rep,
typename _Period>
363 {
return wait_until(__lock, __clock_t::now() + __rtime); }
365 template<
typename _Lock,
typename _Rep,
366 typename _Period,
typename _Predicate>
368 wait_for(_Lock& __lock,
370 {
return wait_until(__lock, __clock_t::now() + __rtime,
std::move(__p)); }
372 #ifdef __cpp_lib_jthread
373 template <
class _Lock,
class _Predicate>
374 bool wait(_Lock& __lock,
378 if (__stoken.stop_requested())
383 std::stop_callback __cb(__stoken, [
this] { notify_all(); });
388 if (__stoken.stop_requested())
394 _Unlock<_Lock> __unlock(__lock);
396 _M_cond.wait(__my_lock2);
401 template <
class _Lock,
class _Clock,
class _Duration,
class _Predicate>
402 bool wait_until(_Lock& __lock,
407 if (__stoken.stop_requested())
412 std::stop_callback __cb(__stoken, [
this] { notify_all(); });
419 if (__stoken.stop_requested())
423 _Unlock<_Lock> __u(__lock);
425 const auto __status = _M_cond.wait_until(__my_lock2, __abs_time);
426 __stop = (__status == std::cv_status::timeout) || __stoken.stop_requested();
436 template <
class _Lock,
class _Rep,
class _Period,
class _Predicate>
437 bool wait_for(_Lock& __lock,
442 auto __abst = std::chrono::steady_clock::now() + __rel_time;
443 return wait_until(__lock,
454 _GLIBCXX_END_NAMESPACE_VERSION
457 #endif // _GLIBCXX_HAS_GTHREADS
459 #endif // _GLIBCXX_CONDITION_VARIABLE
A smart pointer with reference-counted copy semantics.
A movable scoped lock type.
bool uncaught_exception() noexcept
A simple scoped lock type.
Thrown as part of forced unwinding.A magic placeholder class that can be caught by reference to recog...
constexpr enable_if< __is_duration< _ToDur >::value, time_point< _Clock, _ToDur > >::type time_point_cast(const time_point< _Clock, _Dur > &__t)
time_point_cast
constexpr __enable_if_is_duration< _ToDur > duration_cast(const duration< _Rep, _Period > &__d)
duration_cast
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.