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(
40 const std::chrono::duration<Rep, Period>& duration, Tasks&... tasks);
45template <
typename... Tasks,
typename Clock,
typename Duration>
46std::optional<std::size_t> WaitAnyUntil(
47 const std::chrono::time_point<Clock, Duration>& until, Tasks&... tasks);
52template <
typename... Tasks>
53std::optional<std::size_t> WaitAnyUntil(Deadline, Tasks&... tasks);
55template <
typename... Tasks>
56std::optional<std::size_t>
WaitAny(Tasks&... tasks) {
57 return engine::WaitAnyUntil(Deadline
{}, tasks...);
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...);
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...);
76std::optional<std::size_t> DoWaitAny(utils::span<ContextAccessor*> targets,
79template <
typename Container>
80std::optional<std::size_t> WaitAnyFromContainer(Deadline deadline,
82 const auto size = std::size(tasks);
83 std::vector<ContextAccessor*> targets;
84 targets.reserve(size);
86 for (
auto& task : tasks) {
87 targets.push_back(task.TryGetContextAccessor());
90 return DoWaitAny(targets, deadline);
93template <
typename... Tasks>
94std::optional<std::size_t> WaitAnyFromTasks(Deadline deadline,
96 ContextAccessor* wa_elements[]{tasks.TryGetContextAccessor()...};
97 return DoWaitAny(wa_elements, deadline);
100inline std::optional<std::size_t> WaitAnyFromTasks(Deadline) {
return {}; }
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...);
109 return impl::WaitAnyFromTasks(deadline, tasks...);