uvco 0.1
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
uvco::SelectSet< Ts > Class Template Reference

#include <select.h>

Public Types

using Variant = std::variant<Promise<Ts>...>
 
using Tuple = std::tuple<Promise<Ts>...>
 

Public Member Functions

 SelectSet (Promise< Ts >... promises)
 
 ~SelectSet ()
 
bool await_ready () const noexcept
 
void await_suspend (std::coroutine_handle<> handle)
 
std::vector< Variantawait_resume ()
 

Private Member Functions

template<size_t Ix = 0>
void checkPromises (std::vector< Variant > &readyPromises)
 

Private Attributes

Tuple promises_
 
bool resumed_ = false
 

Detailed Description

template<typename... Ts>
class uvco::SelectSet< Ts >

A SelectSet is a set of promises that are awaited simultaneously. The first promise that is ready is returned. If no promise is ready, the coroutine is suspended until one of the promises is ready.

The SelectSet is directly awaitable. For example:

Promise<int> promise1 = []() -> Promise<int> { co_return 1; }();
Promise<int> promise2 = []() -> Promise<int> { co_return 2; }();
std::vector<std::variant<Promise<int>, Promise<int>>> results = co_await
SelectSet{promise1, promise2};
Definition promise.h:76
SelectSet(Promise< Ts >... promises)
Definition select.h:44

It is okay to add an already finished promise to a SelectSet.

It is possible that no events are returned ("spurious wakeup"); make sure that you can handle an empty result vector.

Member Typedef Documentation

◆ Tuple

template<typename... Ts>
using uvco::SelectSet< Ts >::Tuple = std::tuple<Promise<Ts>...>

◆ Variant

template<typename... Ts>
using uvco::SelectSet< Ts >::Variant = std::variant<Promise<Ts>...>

Constructor & Destructor Documentation

◆ SelectSet()

template<typename... Ts>
uvco::SelectSet< Ts >::SelectSet ( Promise< Ts >...  promises)
inlineexplicit
45 : promises_{std::move(promises)...} {}
Tuple promises_
Definition select.h:105

◆ ~SelectSet()

template<typename... Ts>
uvco::SelectSet< Ts >::~SelectSet ( )
inline
47 {
48 if (!resumed_) {
49 std::apply(
50 [](auto &&...promise) { (promise.core()->resetHandle(), ...); },
51 promises_);
52 }
53 }
bool resumed_
Definition select.h:106

Member Function Documentation

◆ await_ready()

template<typename... Ts>
bool uvco::SelectSet< Ts >::await_ready ( ) const
inlinenoexcept
55 {
56 return resumed_ || std::apply(
57 [](auto &&...promise) -> bool {
58 return (promise.ready() || ...);
59 },
60 promises_);
61 }

◆ await_resume()

template<typename... Ts>
std::vector< Variant > uvco::SelectSet< Ts >::await_resume ( )
inline

Returns all promises that are ready. It is possible that no promise is ready, and the returned vector is empty, in the case that two promises were ready at once; one promise scheduled the SelectSet for resumption, we delivered both events, and will be woken up a second time.

TODO: provide a no-/rare-allocation API by reusing a vector or span.

83 {
84 resumed_ = true;
85 std::vector<Variant> readyPromises;
86 checkPromises(readyPromises);
87 return readyPromises;
88 }
void checkPromises(std::vector< Variant > &readyPromises)
Definition select.h:92

◆ await_suspend()

template<typename... Ts>
void uvco::SelectSet< Ts >::await_suspend ( std::coroutine_handle<>  handle)
inline

Register the current coroutine to be resumed when one of the promises is ready.

65 {
66 BOOST_ASSERT_MSG(!resumed_, "A select set can only be used once");
67 std::apply(
68 [handle](auto &&...promise) {
69 ((!promise.core()->stale() ? promise.core()->setHandle(handle)
70 : (void)0),
71 ...);
72 },
73 promises_);
74 }

◆ checkPromises()

template<typename... Ts>
template<size_t Ix = 0>
void uvco::SelectSet< Ts >::checkPromises ( std::vector< Variant > &  readyPromises)
inlineprivate
92 {
93 if constexpr (Ix < sizeof...(Ts)) {
94 using PromiseType = std::tuple_element_t<Ix, Tuple>;
95 PromiseType &promise = std::get<Ix>(promises_);
96 if (promise.ready()) {
97 readyPromises.emplace_back(std::in_place_index<Ix>, std::move(promise));
98 } else {
99 promise.core()->resetHandle();
100 }
101 checkPromises<Ix + 1>(readyPromises);
102 }
103 }

Member Data Documentation

◆ promises_

template<typename... Ts>
Tuple uvco::SelectSet< Ts >::promises_
private

◆ resumed_

template<typename... Ts>
bool uvco::SelectSet< Ts >::resumed_ = false
private

The documentation for this class was generated from the following file: