Nimony

The road to Nim 3

ioring

nimony/lib/std/ioring.nim

Descriptors and -EAGAIN

  • Readiness backends (epoll, kqueue): the descriptors of reads, writes,

accepts, recvfrom and sendto must be O_NONBLOCK (see submitSetNonBlocking; accepted sockets do not inherit it everywhere). The transfer is a plain read/write/accept/recvfrom/sendto, and a blocking descriptor would block the polling thread. A wake that finds nothing to transfer (EAGAIN, or EINTR) leaves the operation pending and re-armed, so these operations never complete with -EAGAIN.

  • io_uring: the kernel honours the descriptor's own mode.

- On an O_NONBLOCK descriptor a read or write can complete with -EAGAIN after a wake that carries no readiness, such as the peer's half-close (POLLRDHUP); callers must handle it. A submitPollAdd for POLLOUT also completes at once with only POLLRDHUP after a half-close, so a poll-then-retry needs a back-off. - On a blocking descriptor the operation parks until it can progress, but it may occupy an io-wq kernel worker while it does, so a peer that never reads can pin one worker per connection.

  • IOCP and WSAPoll sockets are unaffected: Winsock completes asynchronously

or reports WSAEWOULDBLOCK, which the WSAPoll backend already treats as "still pending".