10#include <userver/engine/deadline.hpp>
11#include <userver/utils/meta.hpp>
12#include <userver/utils/span.hpp>
14USERVER_NAMESPACE_BEGIN
32template <
typename... Tasks>
33std::optional<std::size_t>
WaitAny(Tasks&... tasks);
38template <
typename... Tasks,
typename Rep,
typename Period>
39std::optional<std::size_t> WaitAnyFor(
const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks);
44template <
typename... Tasks,
typename Clock,
typename Duration>
45std::optional<std::size_t> WaitAnyUntil(
const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks);
50template <
typename... Tasks>
51std::optional<std::size_t> WaitAnyUntil(Deadline, Tasks&... tasks);
53template <
typename... Tasks>
54std::optional<std::size_t>
WaitAny(Tasks&... tasks) {
55 return engine::WaitAnyUntil(Deadline
{}, tasks...);
58template <
typename... Tasks,
typename Rep,
typename Period>
59std::optional<std::size_t> WaitAnyFor(
const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks) {
60 return engine::WaitAnyUntil(Deadline::FromDuration(duration), tasks...);
63template <
typename... Tasks,
typename Clock,
typename Duration>
64std::optional<std::size_t> WaitAnyUntil(
const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks) {
65 return engine::WaitAnyUntil(Deadline::FromTimePoint(until), tasks...);
72std::optional<std::size_t> DoWaitAny(
utils::span<ContextAccessor*> targets, Deadline deadline);
74template <
typename Container>
75std::optional<std::size_t> WaitAnyFromContainer(Deadline deadline, Container& tasks) {
76 const auto size = std::size(tasks);
77 std::vector<ContextAccessor*> targets;
78 targets.reserve(size);
80 for (
auto& task : tasks) {
81 targets.push_back(task.TryGetContextAccessor());
84 return DoWaitAny(targets, deadline);
87template <
typename... Tasks>
88std::optional<std::size_t> WaitAnyFromTasks(Deadline deadline, Tasks&... tasks) {
89 ContextAccessor* wa_elements[]{tasks.TryGetContextAccessor()...};
90 return DoWaitAny(wa_elements, deadline);
93inline std::optional<std::size_t> WaitAnyFromTasks(Deadline) {
return {}; }
97template <
typename... Tasks>
98std::optional<std::size_t> WaitAnyUntil(Deadline deadline, Tasks&... tasks) {
99 if constexpr (meta::impl::IsSingleRange<Tasks...>()) {
100 return impl::WaitAnyFromContainer(deadline, tasks...);
102 return impl::WaitAnyFromTasks(deadline, tasks...);