How to "block" in an agnostic way?

The semantics issue that @talex5 is pointing out, I think, is the following: there is a difference between suspending on shared result and suspending on a unique resource.

  • If I suspend to wait until a lazy computation is available to all its waiters, cancellation is just a question of performance (if my suspension callback gets called but I was invalidated, the scheduler is going to try to invoke me later only to find that it is useless).
  • But if I suspend until a resource is available that I’m planning to consume, for example “take the next Stream element and give it to me”, then the producer I’m suspending onto needs to learn that I was cancelled for correctess reason, not just efficiency. The resource they produced needs to be given to another waiter, or kept, if I was cancelled.

(Again we see a transactional expectation: either the resource is consumed and I run, or I was cancelled and no resource is wasted.)