Hi! The concurrency explainer contains an example on how to implement non-blocking IO.
write() calls stream.write, forwarding the caller's buffer.
- If
stream.write returns that it successfully copied some bytes without
blocking, write() returns success.
- Otherwise, to avoid blocking:
write() calls [stream.cancel-write] to regain ownership of the
caller's buffer.
- If
select() has not indicated that this file descriptor is ready,
write() starts a zero-length write and returns EWOULDBLOCK.
- Otherwise, to avoid the potential infinite loop:
write() copies the contents of the caller's buffer into an
internal buffer, starts a new stream.write to complete in the
background using the internal buffer, and then returns success.
- The above logic implicitly waits for this background
stream.write
to complete before the file descriptor is considered ready again.
But it also says:
Cancellation is cooperative, (...) allowing the subtask to continue executing for an arbitrary amount of time
Is there a contradiction here?
If the other end of a stream doesn't respect cancellation immediately (which is allowed) or doesn't support cancellation at all (also allowed) the guest will still end up being blocked.