Github   Telegram
Loading...
Searching...
No Matches
wait_any.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <chrono>
7#include <optional>
8#include <vector>
9
11#include <userver/utils/impl/span.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16namespace engine {
17
32template <typename... Tasks>
33std::optional<std::size_t> WaitAny(Tasks&... tasks);
34
38template <typename... Tasks, typename Rep, typename Period>
39std::optional<std::size_t> WaitAnyFor(
40 const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks);
41
45template <typename... Tasks, typename Clock, typename Duration>
46std::optional<std::size_t> WaitAnyUntil(
47 const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks);
48
52template <typename... Tasks>
53std::optional<std::size_t> WaitAnyUntil(Deadline, Tasks&... tasks);
54
55template <typename... Tasks>
56std::optional<std::size_t> WaitAny(Tasks&... tasks) {
57 return engine::WaitAnyUntil(Deadline{}, tasks...);
58}
59
60template <typename... Tasks, typename Rep, typename Period>
61std::optional<std::size_t> WaitAnyFor(
62 const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks) {
63 return engine::WaitAnyUntil(Deadline::FromDuration(duration), tasks...);
64}
65
66template <typename... Tasks, typename Clock, typename Duration>
67std::optional<std::size_t> WaitAnyUntil(
68 const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks) {
69 return engine::WaitAnyUntil(Deadline::FromTimePoint(until), tasks...);
70}
71
72namespace impl {
73
74class ContextAccessor;
75
76std::optional<std::size_t> DoWaitAny(
77 utils::impl::Span<ContextAccessor*> targets, Deadline deadline);
78
79template <typename Container>
80std::optional<std::size_t> WaitAnyFromContainer(Deadline deadline,
81 Container& tasks) {
82 const auto size = std::size(tasks);
83 std::vector<ContextAccessor*> targets;
84 targets.reserve(size);
85
86 for (auto& task : tasks) {
87 targets.push_back(task.TryGetContextAccessor());
88 }
89
90 return DoWaitAny(targets, deadline);
91}
92
93template <typename... Tasks>
94std::optional<std::size_t> WaitAnyFromTasks(Deadline deadline,
95 Tasks&... tasks) {
96 ContextAccessor* wa_elements[]{tasks.TryGetContextAccessor()...};
97 return DoWaitAny(wa_elements, deadline);
98}
99
100inline std::optional<std::size_t> WaitAnyFromTasks(Deadline) { return {}; }
101
102} // namespace impl
103
104template <typename... Tasks>
105std::optional<std::size_t> WaitAnyUntil(Deadline deadline, Tasks&... tasks) {
106 if constexpr (meta::impl::IsSingleRange<Tasks...>()) {
107 return impl::WaitAnyFromContainer(deadline, tasks...);
108 } else {
109 return impl::WaitAnyFromTasks(deadline, tasks...);
110 }
111}
112
113} // namespace engine
114
115USERVER_NAMESPACE_END