userver: userver/engine/condition_variable.hpp Source File
Loading...
Searching...
No Matches
condition_variable.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/condition_variable.hpp
4/// @brief @copybrief engine::ConditionVariable
5
6#include <chrono>
7#include <memory>
8
9#include <userver/engine/condition_variable_status.hpp>
10#include <userver/engine/deadline.hpp>
11#include <userver/engine/impl/condition_variable_any.hpp>
12#include <userver/engine/mutex.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16namespace engine {
17
18/// @ingroup userver_concurrency
19///
20/// @brief std::condition_variable replacement for asynchronous tasks
21///
22/// ## Example usage:
23///
24/// @snippet engine/condition_variable_test.cpp Sample ConditionVariable usage
25///
26/// @see @ref scripts/docs/en/userver/synchronization.md
27class ConditionVariable final {
28public:
29 ConditionVariable();
30 ~ConditionVariable();
31
32 ConditionVariable(const ConditionVariable&) = delete;
33 ConditionVariable(ConditionVariable&&) = delete;
34 ConditionVariable& operator=(const ConditionVariable&) = delete;
35 ConditionVariable& operator=(ConditionVariable&&) = delete;
36
37 /// Suspends execution until notified or cancelled
38 /// @returns `CvStatus::kNoTimeout` if variable was notified
39 /// @returns `CvStatus::kCancelled` if current task is being cancelled
40 [[nodiscard]] CvStatus Wait(std::unique_lock<Mutex>& lock);
41
42 /// @brief Suspends execution until the predicate is `true` when notification
43 /// is received or the task is cancelled
44 /// @returns the value of the predicate
45 template <typename Predicate>
46 [[nodiscard]] bool Wait(std::unique_lock<Mutex>& lock, Predicate&& predicate);
47
48 /// @brief Suspends execution until notified or until the timeout expires or
49 /// until the task is cancelled.
50 /// @returns `CvStatus::kNoTimeout` if variable was notified
51 /// @returns `CvStatus::kTimeout` if `timeout` has expired
52 /// @returns `CvStatus::kCancelled` if current task is being cancelled
53 template <typename Rep, typename Period>
54 CvStatus WaitFor(std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> timeout);
55
56 /// @brief Suspends execution until the predicate is `true` when notified
57 /// or the timeout expires or the task is cancelled.
58 /// @returns the value of the predicate
59 template <typename Rep, typename Period, typename Predicate>
60 bool WaitFor(std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> timeout, Predicate&& predicate);
61
62 /// @brief Suspends execution until notified or the time point is reached or
63 /// the task is cancelled.
64 /// @returns `CvStatus::kNoTimeout` if variable was notified
65 /// @returns `CvStatus::kTimeout` if `until` time point was reached
66 /// @returns `CvStatus::kCancelled` if current task is being cancelled
67 template <typename Clock, typename Duration>
68 CvStatus WaitUntil(std::unique_lock<Mutex>& lock, std::chrono::time_point<Clock, Duration> until);
69
70 /// @brief Suspends execution until notified or the deadline is reached or the
71 /// task is cancelled.
72 /// @returns `CvStatus::kNoTimeout` if variable was notified
73 /// @returns `CvStatus::kTimeout` if deadline was reached
74 /// @returns `CvStatus::kCancelled` if current task is being cancelled
75 CvStatus WaitUntil(std::unique_lock<Mutex>& lock, Deadline deadline);
76
77 /// @brief Suspends execution until the predicate is `true` when notified
78 /// or the time point is reached or the task is cancelled.
79 /// @returns the value of the predicate
80 template <typename Clock, typename Duration, typename Predicate>
81 bool
82 WaitUntil(std::unique_lock<Mutex>& lock, std::chrono::time_point<Clock, Duration> until, Predicate&& predicate);
83
84 /// @brief Suspends execution until the predicate is `true` when notified
85 /// or the deadline is reached or the task is cancelled.
86 /// @returns the value of the predicate
87 template <typename Predicate>
88 bool WaitUntil(std::unique_lock<Mutex>& lock, Deadline deadline, Predicate&& predicate);
89
90 /// Notifies one of the waiting tasks
91 void NotifyOne();
92
93 /// Notifies all waiting tasks
94 void NotifyAll();
95
96private:
97 impl::ConditionVariableAny<Mutex> impl_;
98};
99
100template <typename Predicate>
101bool ConditionVariable::Wait(std::unique_lock<Mutex>& lock, Predicate&& predicate) {
102 return WaitUntil(lock, {}, std::forward<Predicate>(predicate));
103}
104
105template <typename Rep, typename Period>
106CvStatus ConditionVariable::WaitFor(std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> timeout) {
107 return WaitUntil(lock, Deadline::FromDuration(timeout));
108}
109
110template <typename Rep, typename Period, typename Predicate>
111bool ConditionVariable::WaitFor(
112 std::unique_lock<Mutex>& lock,
113 std::chrono::duration<Rep, Period> timeout,
114 Predicate&& predicate
115) {
116 return WaitUntil(lock, Deadline::FromDuration(timeout), std::forward<Predicate>(predicate));
117}
118
119template <typename Clock, typename Duration>
120CvStatus ConditionVariable::WaitUntil(std::unique_lock<Mutex>& lock, std::chrono::time_point<Clock, Duration> until) {
121 return WaitUntil(lock, Deadline::FromTimePoint(until));
122}
123
124template <typename Clock, typename Duration, typename Predicate>
125bool ConditionVariable::WaitUntil(
126 std::unique_lock<Mutex>& lock,
127 std::chrono::time_point<Clock, Duration> until,
128 Predicate&& predicate
129) {
130 return WaitUntil(lock, Deadline::FromTimePoint(until), std::forward<Predicate>(predicate));
131}
132
133template <typename Predicate>
134bool ConditionVariable::WaitUntil(std::unique_lock<Mutex>& lock, Deadline deadline, Predicate&& predicate) {
135 return impl_.WaitUntil(lock, deadline, std::forward<Predicate>(predicate));
136}
137
138} // namespace engine
139
140USERVER_NAMESPACE_END