xref: /openbsd-src/gnu/llvm/libcxx/include/condition_variable (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_CONDITION_VARIABLE
1146035553Spatrick#define _LIBCPP_CONDITION_VARIABLE
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    condition_variable synopsis
1546035553Spatrick
1646035553Spatricknamespace std
1746035553Spatrick{
1846035553Spatrick
1946035553Spatrickenum class cv_status { no_timeout, timeout };
2046035553Spatrick
2146035553Spatrickclass condition_variable
2246035553Spatrick{
2346035553Spatrickpublic:
2446035553Spatrick    condition_variable();
2546035553Spatrick    ~condition_variable();
2646035553Spatrick
2746035553Spatrick    condition_variable(const condition_variable&) = delete;
2846035553Spatrick    condition_variable& operator=(const condition_variable&) = delete;
2946035553Spatrick
3046035553Spatrick    void notify_one() noexcept;
3146035553Spatrick    void notify_all() noexcept;
3246035553Spatrick
3346035553Spatrick    void wait(unique_lock<mutex>& lock);
3446035553Spatrick    template <class Predicate>
3546035553Spatrick        void wait(unique_lock<mutex>& lock, Predicate pred);
3646035553Spatrick
3746035553Spatrick    template <class Clock, class Duration>
3846035553Spatrick        cv_status
3946035553Spatrick        wait_until(unique_lock<mutex>& lock,
4046035553Spatrick                   const chrono::time_point<Clock, Duration>& abs_time);
4146035553Spatrick
4246035553Spatrick    template <class Clock, class Duration, class Predicate>
4346035553Spatrick        bool
4446035553Spatrick        wait_until(unique_lock<mutex>& lock,
4546035553Spatrick                   const chrono::time_point<Clock, Duration>& abs_time,
4646035553Spatrick                   Predicate pred);
4746035553Spatrick
4846035553Spatrick    template <class Rep, class Period>
4946035553Spatrick        cv_status
5046035553Spatrick        wait_for(unique_lock<mutex>& lock,
5146035553Spatrick                 const chrono::duration<Rep, Period>& rel_time);
5246035553Spatrick
5346035553Spatrick    template <class Rep, class Period, class Predicate>
5446035553Spatrick        bool
5546035553Spatrick        wait_for(unique_lock<mutex>& lock,
5646035553Spatrick                 const chrono::duration<Rep, Period>& rel_time,
5746035553Spatrick                 Predicate pred);
5846035553Spatrick
5946035553Spatrick    typedef pthread_cond_t* native_handle_type;
6046035553Spatrick    native_handle_type native_handle();
6146035553Spatrick};
6246035553Spatrick
6346035553Spatrickvoid notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
6446035553Spatrick
6546035553Spatrickclass condition_variable_any
6646035553Spatrick{
6746035553Spatrickpublic:
6846035553Spatrick    condition_variable_any();
6946035553Spatrick    ~condition_variable_any();
7046035553Spatrick
7146035553Spatrick    condition_variable_any(const condition_variable_any&) = delete;
7246035553Spatrick    condition_variable_any& operator=(const condition_variable_any&) = delete;
7346035553Spatrick
7446035553Spatrick    void notify_one() noexcept;
7546035553Spatrick    void notify_all() noexcept;
7646035553Spatrick
7746035553Spatrick    template <class Lock>
7846035553Spatrick        void wait(Lock& lock);
7946035553Spatrick    template <class Lock, class Predicate>
8046035553Spatrick        void wait(Lock& lock, Predicate pred);
8146035553Spatrick
8246035553Spatrick    template <class Lock, class Clock, class Duration>
8346035553Spatrick        cv_status
8446035553Spatrick        wait_until(Lock& lock,
8546035553Spatrick                   const chrono::time_point<Clock, Duration>& abs_time);
8646035553Spatrick
8746035553Spatrick    template <class Lock, class Clock, class Duration, class Predicate>
8846035553Spatrick        bool
8946035553Spatrick        wait_until(Lock& lock,
9046035553Spatrick                   const chrono::time_point<Clock, Duration>& abs_time,
9146035553Spatrick                   Predicate pred);
9246035553Spatrick
9346035553Spatrick    template <class Lock, class Rep, class Period>
9446035553Spatrick        cv_status
9546035553Spatrick        wait_for(Lock& lock,
9646035553Spatrick                 const chrono::duration<Rep, Period>& rel_time);
9746035553Spatrick
9846035553Spatrick    template <class Lock, class Rep, class Period, class Predicate>
9946035553Spatrick        bool
10046035553Spatrick        wait_for(Lock& lock,
10146035553Spatrick                 const chrono::duration<Rep, Period>& rel_time,
10246035553Spatrick                 Predicate pred);
10346035553Spatrick};
10446035553Spatrick
10546035553Spatrick}  // std
10646035553Spatrick
10746035553Spatrick*/
10846035553Spatrick
109*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
11046035553Spatrick#include <__config>
111*4bdff4beSrobert#include <__memory/shared_ptr.h>
112*4bdff4beSrobert#include <__memory/unique_ptr.h>
11346035553Spatrick#include <__mutex_base>
114*4bdff4beSrobert#include <version>
11546035553Spatrick
11646035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
11746035553Spatrick#  pragma GCC system_header
11846035553Spatrick#endif
11946035553Spatrick
12046035553Spatrick#ifndef _LIBCPP_HAS_NO_THREADS
12146035553Spatrick
12246035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
12346035553Spatrick
12446035553Spatrickclass _LIBCPP_TYPE_VIS condition_variable_any
12546035553Spatrick{
12646035553Spatrick    condition_variable __cv_;
12746035553Spatrick    shared_ptr<mutex>  __mut_;
12846035553Spatrickpublic:
12946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
13046035553Spatrick    condition_variable_any();
13146035553Spatrick
13246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
13346035553Spatrick    void notify_one() _NOEXCEPT;
13446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
13546035553Spatrick    void notify_all() _NOEXCEPT;
13646035553Spatrick
13746035553Spatrick    template <class _Lock>
13846035553Spatrick        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
13946035553Spatrick        void wait(_Lock& __lock);
14046035553Spatrick    template <class _Lock, class _Predicate>
14146035553Spatrick        _LIBCPP_INLINE_VISIBILITY
14246035553Spatrick        void wait(_Lock& __lock, _Predicate __pred);
14346035553Spatrick
14446035553Spatrick    template <class _Lock, class _Clock, class _Duration>
14546035553Spatrick        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
14646035553Spatrick        cv_status
14746035553Spatrick        wait_until(_Lock& __lock,
14846035553Spatrick                   const chrono::time_point<_Clock, _Duration>& __t);
14946035553Spatrick
15046035553Spatrick    template <class _Lock, class _Clock, class _Duration, class _Predicate>
15146035553Spatrick        bool
15246035553Spatrick        _LIBCPP_INLINE_VISIBILITY
15346035553Spatrick        wait_until(_Lock& __lock,
15446035553Spatrick                   const chrono::time_point<_Clock, _Duration>& __t,
15546035553Spatrick                   _Predicate __pred);
15646035553Spatrick
15746035553Spatrick    template <class _Lock, class _Rep, class _Period>
15846035553Spatrick        cv_status
15946035553Spatrick        _LIBCPP_INLINE_VISIBILITY
16046035553Spatrick        wait_for(_Lock& __lock,
16146035553Spatrick                 const chrono::duration<_Rep, _Period>& __d);
16246035553Spatrick
16346035553Spatrick    template <class _Lock, class _Rep, class _Period, class _Predicate>
16446035553Spatrick        bool
16546035553Spatrick        _LIBCPP_INLINE_VISIBILITY
16646035553Spatrick        wait_for(_Lock& __lock,
16746035553Spatrick                 const chrono::duration<_Rep, _Period>& __d,
16846035553Spatrick                 _Predicate __pred);
16946035553Spatrick};
17046035553Spatrick
17146035553Spatrickinline
17246035553Spatrickcondition_variable_any::condition_variable_any()
17346035553Spatrick    : __mut_(make_shared<mutex>()) {}
17446035553Spatrick
17546035553Spatrickinline
17646035553Spatrickvoid
17746035553Spatrickcondition_variable_any::notify_one() _NOEXCEPT
17846035553Spatrick{
17946035553Spatrick    {lock_guard<mutex> __lx(*__mut_);}
18046035553Spatrick    __cv_.notify_one();
18146035553Spatrick}
18246035553Spatrick
18346035553Spatrickinline
18446035553Spatrickvoid
18546035553Spatrickcondition_variable_any::notify_all() _NOEXCEPT
18646035553Spatrick{
18746035553Spatrick    {lock_guard<mutex> __lx(*__mut_);}
18846035553Spatrick    __cv_.notify_all();
18946035553Spatrick}
19046035553Spatrick
19146035553Spatrickstruct __lock_external
19246035553Spatrick{
19346035553Spatrick    template <class _Lock>
19446035553Spatrick    void operator()(_Lock* __m) {__m->lock();}
19546035553Spatrick};
19646035553Spatrick
19746035553Spatricktemplate <class _Lock>
19846035553Spatrickvoid
19946035553Spatrickcondition_variable_any::wait(_Lock& __lock)
20046035553Spatrick{
20146035553Spatrick    shared_ptr<mutex> __mut = __mut_;
20246035553Spatrick    unique_lock<mutex> __lk(*__mut);
20346035553Spatrick    __lock.unlock();
20446035553Spatrick    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
20546035553Spatrick    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
20646035553Spatrick    __cv_.wait(__lk);
20746035553Spatrick}  // __mut_.unlock(), __lock.lock()
20846035553Spatrick
20946035553Spatricktemplate <class _Lock, class _Predicate>
21046035553Spatrickinline
21146035553Spatrickvoid
21246035553Spatrickcondition_variable_any::wait(_Lock& __lock, _Predicate __pred)
21346035553Spatrick{
21446035553Spatrick    while (!__pred())
21546035553Spatrick        wait(__lock);
21646035553Spatrick}
21746035553Spatrick
21846035553Spatricktemplate <class _Lock, class _Clock, class _Duration>
21946035553Spatrickcv_status
22046035553Spatrickcondition_variable_any::wait_until(_Lock& __lock,
22146035553Spatrick                                   const chrono::time_point<_Clock, _Duration>& __t)
22246035553Spatrick{
22346035553Spatrick    shared_ptr<mutex> __mut = __mut_;
22446035553Spatrick    unique_lock<mutex> __lk(*__mut);
22546035553Spatrick    __lock.unlock();
22646035553Spatrick    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
22746035553Spatrick    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
22846035553Spatrick    return __cv_.wait_until(__lk, __t);
22946035553Spatrick}  // __mut_.unlock(), __lock.lock()
23046035553Spatrick
23146035553Spatricktemplate <class _Lock, class _Clock, class _Duration, class _Predicate>
23246035553Spatrickinline
23346035553Spatrickbool
23446035553Spatrickcondition_variable_any::wait_until(_Lock& __lock,
23546035553Spatrick                                   const chrono::time_point<_Clock, _Duration>& __t,
23646035553Spatrick                                   _Predicate __pred)
23746035553Spatrick{
23846035553Spatrick    while (!__pred())
23946035553Spatrick        if (wait_until(__lock, __t) == cv_status::timeout)
24046035553Spatrick            return __pred();
24146035553Spatrick    return true;
24246035553Spatrick}
24346035553Spatrick
24446035553Spatricktemplate <class _Lock, class _Rep, class _Period>
24546035553Spatrickinline
24646035553Spatrickcv_status
24746035553Spatrickcondition_variable_any::wait_for(_Lock& __lock,
24846035553Spatrick                                 const chrono::duration<_Rep, _Period>& __d)
24946035553Spatrick{
25046035553Spatrick    return wait_until(__lock, chrono::steady_clock::now() + __d);
25146035553Spatrick}
25246035553Spatrick
25346035553Spatricktemplate <class _Lock, class _Rep, class _Period, class _Predicate>
25446035553Spatrickinline
25546035553Spatrickbool
25646035553Spatrickcondition_variable_any::wait_for(_Lock& __lock,
25746035553Spatrick                                 const chrono::duration<_Rep, _Period>& __d,
25846035553Spatrick                                 _Predicate __pred)
25946035553Spatrick{
26046035553Spatrick    return wait_until(__lock, chrono::steady_clock::now() + __d,
26146035553Spatrick                      _VSTD::move(__pred));
26246035553Spatrick}
26346035553Spatrick
26446035553Spatrick_LIBCPP_FUNC_VIS
265*4bdff4beSrobertvoid notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>);
26646035553Spatrick
26746035553Spatrick_LIBCPP_END_NAMESPACE_STD
26846035553Spatrick
26946035553Spatrick#endif // !_LIBCPP_HAS_NO_THREADS
27046035553Spatrick
271*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
272*4bdff4beSrobert#  include <concepts>
273*4bdff4beSrobert#  include <type_traits>
274*4bdff4beSrobert#endif
275*4bdff4beSrobert
27646035553Spatrick#endif // _LIBCPP_CONDITION_VARIABLE
277