Created on 2025-02-03.00:00:00 last changed 2 days ago
[ This touches the same text as LWG 4203. ]
Imported from cplusplus/sender-receiver #304.
[exec.schedule.from]/p11 specifies `shedule_from`'s completion operation as follows:
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept
-> void {
using result_t = decayed-tuple<Tag, Args...>;
constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>;
try {
state.async-result.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
} catch (...) {
if constexpr (!nothrow) {
set_error(std::move(rcvr), current_exception());
return;
}
}
start(state.op-state);
};
so if emplacing the result tuple throws, `set_error` is immediately called on the downstream receiver. no attempt is made to post the completion to the specified scheduler. this is probably not the right behavior.
Suggested resolution
The right thing, i think, is to catch the exception, emplace the `exception_ptr` into the `async-result` variant, and then start the schedule operation, as shown below:
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept
-> void {
using result_t = decayed-tuple<Tag, Args...>;
constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>;
try {
state.async-result.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
} catch(...) {
if constexpr (nothrow)
state.async-result.template emplace<tuple<set_error_t, exception_ptr>>(set_error, current_exception());
}
}
start(state.op-state);
}
we also need to change how we specify the variant type of `state.async-result`:
Let `Sigs` be a pack of the arguments to the `completion_signatures` specialization named bycompletion_signatures_of_t<child-type<Sndr>, env_of_t<Rcvr>>
. Letas-tuple
be an alias templatethat transforms a completion signature `Tag(Args...)` into the tuple specializationsuch thatdecayed-tuple<Tag, Args...>
.as-tuple<Tag(Args...)>
denotes the tuple specializationdecayed-tuple<Tag, Args...>
, and letis-nothrow-decay-copy-sig
be a variable template such thatis-nothrow-decay-copy-sig<Tag(Args...)>
is a core constant expression of type `bool const` and whose value is `true` if the types `Args...` are all nothrow decay-copyable, and `false` otherwise. Leterror-completion
be a pack consisting of the type `set_error_t(exception_ptr)` if(is-nothrow-decay-copy-sig<Sigs> &&...)
is `false`, and an empty pack otherwise. Then `variant_t` denotes the typevariant<monostate, as-tuple<Sigs>..., error-completion...>
, except with duplicate types removed.
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-02-03 16:56:11 | admin | set | messages: + msg14563 |
2025-02-03 00:00:00 | admin | create |