#pragma once #if !defined(INCLUDE_LIBRARY_THREADING_FUTURE_WAIT_ANY_INL_H) #error "you should never include wait_any_inl.h directly" #endif #include "subscription.h" #include namespace NThreading::NWait { namespace NPrivate { class TWaitAny final : public NThreading::NPrivate::TWait { private: static constexpr bool RevertOnSignaled = true; using TBase = NThreading::NPrivate::TWait; friend TBase; private: TWaitAny(TSubscriptionManagerPtr manager) : TBase(std::move(manager)) { } template void BeforeSubscribe(TFutures const& futures) { Y_ENSURE(std::size(futures) > 0, "Futures set cannot be empty"); } template void Set(TFuture const& future) { with_lock (TBase::Lock) { TBase::Unsubscribe(); try { future.TryRethrow(); TBase::Promise.TrySetValue(); } catch (...) { TBase::Promise.TrySetException(std::current_exception()); } } } }; } template TFuture WaitAny(TFutures const& futures, TSubscriptionManagerPtr manager, TCallbackExecutor&& executor) { return NThreading::NPrivate::Wait(futures, std::move(manager), std::forward(executor)); } template TFuture WaitAny(std::initializer_list const> futures, TSubscriptionManagerPtr manager, TCallbackExecutor&& executor) { return NThreading::NPrivate::Wait(futures, std::move(manager), std::forward(executor)); } template TFuture WaitAny(TFuture const& future1, TFuture const& future2, TSubscriptionManagerPtr manager, TCallbackExecutor&& executor) { return NThreading::NPrivate::Wait(future1, future2, std::move(manager), std::forward(executor)); } }