But according to the specification, sync_wait in fact never tries to stop its operation (and it makes perrect sense, since there is no general thread cancellation machinery like Java's Thread.interrupt).
So sync_wait may only receive stopped result if sender decided to stop itself. But if receiver started some operation, it did not lose interest in it, and this operation suddenly stopped, then it should be treated as failure, not as an normal outcome.
Also, please consider following (pseudo)code
// for the simplicity, assume that channel does not support close() operation
void do_work(channel<Task> tasks, channel<Task> also_tasks) {
while (true) {
optional<Task> task = sync_wait(when_any(tasks.recv(), also_tasks().recv()));
if (!task) {
// ???
}
process_task(*task);
}
}
Here, task has to be declared optional, because when_any returns optional. However it is clear that is never empty in fact - although when_any may stop its child operations internally, it will not stop both. But since this invariant is not encoded in type system, user has following options:
Fill ??? with explanation of the situation
Replace // ??? with terminate()-like call.
Neither option is perfect. It is desirable that this invariant ("task always contains some task") is encoded in type system instead, which avoids both reader confusion and having dead code.
Therefore it seems to me that
1) it should be illegal (*) for sender to invoke set_stopped if operation was not requested to stop; in particular, if receiver passes unstoppable token, it's set_stopped function should never be called.
1) sync_wait should not return std::optional.
For example it may be declared UB, but I do not insist on this.
P.S. sorry if this repository is wrong place for questions or if this question was already discussed.
Any sender may end with stopped for any reason it chooses. It is not a decision made by the receiver. sync_wait must be able to handle the case when a sender completes with stopped.
As written in https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2023/p2300r7.html#design-sender-consumer-sync_wait (I refer to R7, but AFAIK this place was not modified here in repository),
sync_wait(snd)
returnsstd::optional<value_t>
, wherestd::nullopt
means that task, described bysnd
, was stopped.But according to the specification,
sync_wait
in fact never tries to stop its operation (and it makes perrect sense, since there is no general thread cancellation machinery like Java'sThread.interrupt
).So
sync_wait
may only receivestopped
result if sender decided to stop itself. But if receiver started some operation, it did not lose interest in it, and this operation suddenly stopped, then it should be treated as failure, not as an normal outcome.Also, please consider following (pseudo)code
Here,
task
has to be declaredoptional
, becausewhen_any
returns optional. However it is clear that is never empty in fact - although when_any may stop its child operations internally, it will not stop both. But since this invariant is not encoded in type system, user has following options:???
with explanation of the situation// ???
withterminate()
-like call.Neither option is perfect. It is desirable that this invariant ("task always contains some task") is encoded in type system instead, which avoids both reader confusion and having dead code.
Therefore it seems to me that 1) it should be illegal (*) for sender to invoke
set_stopped
if operation was not requested to stop; in particular, if receiver passes unstoppable token, it'sset_stopped
function should never be called. 1) sync_wait should not returnstd::optional
.P.S. sorry if this repository is wrong place for questions or if this question was already discussed.