userver: userver/engine/impl/condition_variable_any.hpp Source File
Loading...
Searching...
No Matches
condition_variable_any.hpp
1#pragma once
2
3#include <mutex> // for std::unique_lock
4
5#include <userver/engine/condition_variable_status.hpp>
6#include <userver/engine/deadline.hpp>
7#include <userver/engine/impl/wait_list_fwd.hpp>
8
9// TODO remove extra includes
10#include <userver/engine/task/task.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace engine::impl {
15
16void OnConditionVariableSpuriousWakeup();
17
18template <typename MutexType>
19class ConditionVariableAny {
20 public:
21 ConditionVariableAny();
22 ~ConditionVariableAny();
23
24 ConditionVariableAny(const ConditionVariableAny&) = delete;
25 ConditionVariableAny(ConditionVariableAny&&) = delete;
26 ConditionVariableAny& operator=(const ConditionVariableAny&) = delete;
27 ConditionVariableAny& operator=(ConditionVariableAny&&) = delete;
28
29 CvStatus WaitUntil(std::unique_lock<MutexType>&, Deadline);
30
31 template <typename Predicate>
32 bool WaitUntil(std::unique_lock<MutexType>&, Deadline, Predicate&&);
33
34 void NotifyOne();
35 void NotifyAll();
36
37 private:
38 FastPimplWaitList waiters_;
39};
40
41template <typename MutexType>
42template <typename Predicate>
43bool ConditionVariableAny<MutexType>::WaitUntil(
44 std::unique_lock<MutexType>& lock, Deadline deadline,
45 Predicate&& predicate) {
46 bool predicate_result = predicate();
47 auto status = CvStatus::kNoTimeout;
48 while (!predicate_result && status == CvStatus::kNoTimeout) {
49 status = WaitUntil(lock, deadline);
50 predicate_result = predicate();
51 if (!predicate_result && status == CvStatus::kNoTimeout) {
52 impl::OnConditionVariableSpuriousWakeup();
53 }
54 }
55 return predicate_result;
56}
57
58} // namespace engine::impl
59
60USERVER_NAMESPACE_END