Skip to content

Non-blocking I/O without cancellation #617

Description

@badeend

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions