poll
nimony/lib/std/ioring/backends/poll.nim
var reArmEvent: proc (fd: int32, events: set[IoEvent], alreadyRegistered: bool): bool {.nimcall.}proc armEventsForFd(fd: int32): set[IoEvent]The union of the directions every op currently pending on
fdwaits for.It has to be the union, never one op's own direction: the registration is keyed by fd, and epoll's
EPOLL_CTL_MODreplaces the interest set. Arming with just the newest op's direction therefore silently disarms the others —submitWrite(fd)followed bysubmitRead(fd)would leave the fd watched for EPOLLIN only and the pending write would never be woken.const ArmFailed: int64Completion result for an op on a fd that could not be armed — the same value a failed read or write reports.
proc failPendingForFd(fd: int32)Complete every op pending on
fd. Nothing will make them ready once the fd cannot be armed, so otherwise they park forever.proc submitForPoll(fd: int32; alreadyRegistered: bool)Arm
fdfor every op pending on it, including the one just allocated by the caller (allocSlothas already linked it into the fd's list).An op with no fd has nothing to arm, and arming anyway is not merely useless — the arena lists ops by fd, so every fd-less op shares the
-1bucket. On epoll,epoll_ctlon-1fails with EBADF, which is read as "this fd will never deliver readiness" and fails every op in the bucket: one nop would complete every pending timer with an error. On kqueue the arm silently does nothing instead, so the same nop hangs forever. Neither is a bug the caller can do anything about, so fd-less ops do not come here at all.proc startConnect(fd: int32; idx: int64): boolKick off a non-blocking connect on the op in slot
idx. True when the attempt is under way and the poller should watch for writability.False means it is already over — and then this completes the slot, because nothing else will: an op that is never armed gets no readiness event, so leaving it here would park the caller until its deadline no matter how the connect actually went.
proc processFd(fd: int32; firedEvents: set[IoEvent])Dispatch every pending op on
fdwhose direction actually matches the readiness that just fired.firedEvents(as delivered by the poller) is authoritative: a write-readiness wakeup must not drive a still-pending read op (and vice versa) — the fd may be registered for both directions at once (e.g. a socket with an in-flight read and an in-flight write), and only the direction that actually fired has data ready / a free send buffer.