Skip to content

Should when_all and split check the receiver's stop token for stop_requested() and call set_stopped? #295

Open
@jiixyj

Description

@jiixyj

when_all's start function executes this code:

  state.on_stop.emplace(
    get_stop_token(get_env(rcvr)),
    on-stop-request{state.stop_src});
  if (state.stop_src.stop_requested()) {
    state.on_stop.reset();
    set_stopped(std::move(rcvr));
  } else {
    (start(ops), ...);
  }

...so it checks the receivers stop token and calls set_stopped if this is set. The problem with this is that I as the user cannot really disable this behavior. If I wrap the when_all in unstoppable the whole thing cannot be stopped any longer. But I might want the child operations to react to cancellation requests from the outside.

Opting into this behavior is much easier, by wrapping the when_all sender into a sender that does this checking.

This makes it sometimes impossible to use when_all as a building block for other things. For example, the current wording of let_async_scope (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3296r1.html) uses when_all to ensure the async scope is joined, like this:

    auto result_sender = when_all(just_error(std::current_exception()), state.scope.join());

...the problem with this is that when the environment sent a cancellation request earlier, neither of the two senders will be called, not even the async scope's join sender, making this incorrect, I believe.

Metadata

Metadata

Labels

needs-proposed-resolutionThis issue does not yet have a proposed resolution but needs one

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions