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 {
28 public:
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,
55 std::chrono::duration<Rep, Period> timeout);
56
57 /// @brief Suspends execution until the predicate is `true` when notified
58 /// or the timeout expires or the task is cancelled.
59 /// @returns the value of the predicate
60 template <typename Rep, typename Period, typename Predicate>
61 bool WaitFor(std::unique_lock<Mutex>& lock,
62 std::chrono::duration<Rep, Period> timeout,
63 Predicate&& predicate);
64
65 /// @brief Suspends execution until notified or the time point is reached or
66 /// the task is cancelled.
67 /// @returns `CvStatus::kNoTimeout` if variable was notified
68 /// @returns `CvStatus::kTimeout` if `until` time point was reached
69 /// @returns `CvStatus::kCancelled` if current task is being cancelled
70 template <typename Clock, typename Duration>
71 CvStatus WaitUntil(std::unique_lock<Mutex>& lock,
72 std::chrono::time_point<Clock, Duration> until);
73
74 /// @brief Suspends execution until notified or the deadline is reached or the
75 /// task is cancelled.
76 /// @returns `CvStatus::kNoTimeout` if variable was notified
77 /// @returns `CvStatus::kTimeout` if deadline was reached
78 /// @returns `CvStatus::kCancelled` if current task is being cancelled
79 CvStatus WaitUntil(std::unique_lock<Mutex>& lock, Deadline deadline);
80
81 /// @brief Suspends execution until the predicate is `true` when notified
82 /// or the time point is reached or the task is cancelled.
83 /// @returns the value of the predicate
84 template <typename Clock, typename Duration, typename Predicate>
85 bool WaitUntil(std::unique_lock<Mutex>& lock,
86 std::chrono::time_point<Clock, Duration> until,
87 Predicate&& predicate);
88
89 /// @brief Suspends execution until the predicate is `true` when notified
90 /// or the deadline is reached or the task is cancelled.
91 /// @returns the value of the predicate
92 template <typename Predicate>
93 bool WaitUntil(std::unique_lock<Mutex>& lock, Deadline deadline,
94 Predicate&& predicate);
95
96 /// Notifies one of the waiting tasks
97 void NotifyOne();
98
99 /// Notifies all waiting tasks
100 void NotifyAll();
101
102 private:
103 impl::ConditionVariableAny<Mutex> impl_;
104};
105
106template <typename Predicate>
107bool ConditionVariable::Wait(std::unique_lock<Mutex>& lock,
108 Predicate&& predicate) {
109 return WaitUntil(lock, {}, std::forward<Predicate>(predicate));
110}
111
112template <typename Rep, typename Period>
113CvStatus ConditionVariable::WaitFor(
114 std::unique_lock<Mutex>& lock, std::chrono::duration<Rep, Period> timeout) {
115 return WaitUntil(lock, Deadline::FromDuration(timeout));
116}
117
118template <typename Rep, typename Period, typename Predicate>
119bool ConditionVariable::WaitFor(std::unique_lock<Mutex>& lock,
120 std::chrono::duration<Rep, Period> timeout,
121 Predicate&& predicate) {
122 return WaitUntil(lock, Deadline::FromDuration(timeout),
123 std::forward<Predicate>(predicate));
124}
125
126template <typename Clock, typename Duration>
127CvStatus ConditionVariable::WaitUntil(
128 std::unique_lock<Mutex>& lock,
129 std::chrono::time_point<Clock, Duration> until) {
130 return WaitUntil(lock, Deadline::FromTimePoint(until));
131}
132
133template <typename Clock, typename Duration, typename Predicate>
134bool ConditionVariable::WaitUntil(
135 std::unique_lock<Mutex>& lock,
136 std::chrono::time_point<Clock, Duration> until, Predicate&& predicate) {
137 return WaitUntil(lock, Deadline::FromTimePoint(until),
138 std::forward<Predicate>(predicate));
139}
140
141template <typename Predicate>
142bool ConditionVariable::WaitUntil(std::unique_lock<Mutex>& lock,
143 Deadline deadline, Predicate&& predicate) {
144 return impl_.WaitUntil(lock, deadline, std::forward<Predicate>(predicate));
145}
146
147} // namespace engine
148
149USERVER_NAMESPACE_END