run ready tasksTasks queue their reads, writes, accepts and closes. Nothing enters the kernel yet.
io_uring_enterSubmit everything, collect everything that is ready. One system call.
fire timersA timing wheel in user space: arming and cancelling make no system call.
↺ repeat
- Wakers
- A waker does not own its task; it holds a slot number and a handle to the worker. Wakers are
Send + Sync although tasks are not, without unsafe. - Writes
- Ownership passing:
write_all(buf) returns (result, buf). The kernel keeps a pointer to the buffer until it is done, and this API makes that sound in Rust. - Backpressure
- A slow reader has its multishot receive paused, so TCP slows the sender. A dry pool reclaims buffers that hold unread data. One stalled connection cannot starve the rest.
- Timers
- A hierarchical timing wheel, six levels of 64 slots, 1 ms ticks. Nearly every timer is an I/O timeout that is cancelled before it fires, so both are O(1).
- Panics
- A panic in a task is caught and reported through its
JoinHandle. One bad connection does not take down the worker. - Shutdown
- With a grace period, requests in progress are answered. Then: cancel everything, wait for the kernel to confirm, free. If confirmation does not come, leak on purpose.
- UDP
- Multishot
recvmsg on the same buffer pool as TCP. Every worker binds its own SO_REUSEPORT socket and recv_from is cancel safe. - Old kernels
- Three ring setups, tried in order:
DEFER_TASKRUN (6.1+), COOP_TASKRUN (6.0), no flags. The fallbacks are tested on every change by forcing them.