slots
nimony/lib/std/ioring/core/slots.nim
type SlotObj = object op: OpContext cancelRes: int64 timerPos: int64 backendData: pointer nextInFd: ref SlotObj prevInFd: ref SlotObj
type Slot = ref SlotObj not niltype SlotArena = object fdHeads: seq[ref SlotObj]
proc init(a: var SlotArena)proc toPointer(s: ref SlotObj not nil): pointer not nilThe address a backend hands the kernel for
s.proc toSlot(p: pointer): ref SlotObj not nilThe slot whose
toPointerisp. The slot must still be in flight.proc allocSlot(a: var SlotArena; op: OpContext): ref SlotObjA fresh slot holding
op, ornilwhen memory is exhausted.proc freeSlot(a: var SlotArena; s: ref SlotObj not nil)Unlink
sfrom its fd's list, which drops the ring's reference to it. The links are moved, not copied: every refcount update is atomic.proc hasPendingForFd(a: var SlotArena; fd: int32): boolvar, likeslotsForFd, purely to avoid copying the arena — see there.iterator slotsForFd(a: var SlotArena; fd: int32): ref SlotObj not nilYield every in-flight slot for
fd, O(k) in the number of ops on this fd rather than O(ops in flight).aisvareven though nothing here writes to it: the callers all pass a seq element (gSlots[lane].slotsForFd(...)), and for a non-varparameter that materialises a copy of the arena's tables on every call.varpasses the arena itself.The body may complete the slot it was handed (
complete/closeFdboth do), so the successor is taken before yielding; holding it also keeps it alive while the body runs.iterator pendingFds(a: var SlotArena): int32Every fd that has at least one in-flight slot. The table is mutated by
freeSlot, so a caller that completes ops must collect the fds first and dispatch afterwards — nevercompletefrom inside this loop.iterator allSlots(a: var SlotArena): ref SlotObj not nilEvery in-flight slot. The body must not complete any of them.