userver: userver/engine/condition_variable.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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