61 uring standard library
The uring module provides low-level Linux io_uring kernel submission and completion rings for non-blocking asynchronous system calls.
#use uring61.1 Platform requirements
The uring module depends directly on the Linux kernel io_uring interface (kernel 5.1+). It is available exclusively on Linux targets.
[!NOTE] Even on supported kernels, environment policies (such as restrictive Docker seccomp profiles, unprivileged container namespaces, or system-wide
kernel.io_uring_disabledsysctl settings) can causeuring::newto fail with runtime permission or operation errors.
61.2 Core structures
#type CQE (
user_data: Int,
res: Int,
flags: Int
)
#type Ring (
fd: Int,
sq_ptr: Addr,
sq_sz: Int,
sqes_ptr: Addr,
sqes_sz: Int,
cq_ptr: Addr,
cq_sz: Int,
sq_head_off: Int,
sq_tail_off: Int,
sq_mask_off: Int,
sq_arr_off: Int,
cq_head_off: Int,
cq_tail_off: Int,
cq_mask_off: Int,
cq_cqes_off: Int,
sq_entries: Int,
cq_entries: Int
)61.3 Function catalog
| Function | Signature | Description |
|---|---|---|
uring::new |
Int => < Ring | String > |
Initializes an io_uring ring with the requested number of submission queue entries |
uring::prep_nop |
Ring, Int => <> |
Prepares a no-operation submission; returns <-> if the queue is full |
uring::prep_read |
Ring, Int, Addr, Int, Int => <> |
Prepares an asynchronous read at current file offset (-1), advancing position on completion |
uring::prep_read_at |
Ring, Int, Addr, Int, Int, Int => <> |
Prepares an asynchronous read at an explicit file offset (off), preserving file position |
uring::prep_write |
Ring, Int, Addr, Int, Int => <> |
Prepares an asynchronous write at current file offset (-1), advancing position on completion |
uring::prep_write_at |
Ring, Int, Addr, Int, Int, Int => <> |
Prepares an asynchronous write at an explicit file offset (off), preserving file position |
uring::prep_pipe_read |
Ring, Int, Addr, Int, Int => <> |
Prepares an asynchronous stream/pipe/PTY read (off = 0) |
uring::prep_pipe_write |
Ring, Int, Addr, Int, Int => <> |
Prepares an asynchronous stream/pipe/PTY write (off = 0) |
uring::prep_close |
Ring, Int, Int => <> |
Prepares an asynchronous file descriptor close operation |
uring::prep_send |
Ring, Int, Addr, Int, Int, Int => <> |
Prepares an asynchronous socket send operation |
uring::prep_recv |
Ring, Int, Addr, Int, Int, Int => <> |
Prepares an asynchronous socket receive operation |
uring::prep_accept |
Ring, Int, Addr, Addr, Int, Int => <> |
Prepares an asynchronous socket accept operation |
uring::prep_timeout |
Ring, Addr, Int, Int, Int => <> |
Prepares a timer- or completion-count-based timeout |
uring::prep_timeout_ms |
Ring, Addr, Int, Int => <> |
Populates a 16-byte Timespec at ts_ptr from timeout_ms and prepares OP_TIMEOUT |
uring::prep_cancel |
Ring, Int, Int => <> |
Prepares an asynchronous cancellation request targeting a 64-bit user_data |
uring::sq_space |
Ring => Int |
Returns the number of available slots remaining in the submission queue |
uring::submit |
Ring => Int |
Enters kernel and submits pending SQEs via io_uring_enter |
uring::submit_and_wait |
Ring, Int => Int |
Submits pending SQEs and blocks until at least wait_nr CQEs complete |
uring::peek_cqe |
Ring => < CQE | > |
Non-blocking check for a completion event; copies CQE before advancing head pointer |
uring::wait_cqe |
Ring => < CQE | String > |
Checks for ready CQE or blocks via submit_and_wait(ring, 1) |
uring::reap |
Ring => CQEs |
Drains all currently ready CQEs into a growable array |
uring::drain_pipes |
Ring, PipeFds => < PipeOutputs | String > |
Multiplexes concurrent async OP_READ submissions across multiple pipes until EOF |
uring::close |
Ring => () |
Unmaps submission/completion ring memory and closes the ring file descriptor |
61.4 Operational semantics
61.4.1 Submission queue capacity
Submission queue preparation (prep_*) checks available ring capacity (sq_space(ring)). If the ring is full, preparation returns <-> immediately without modifying sq_tail or overwriting pending submissions. Callers must invoke uring::submit to flush pending entries and free ring capacity.
61.4.2 Buffer lifetimes and memory stability
Standard operations (prep_read, prep_write, prep_send, prep_recv) use ordinary buffered/page-cache I/O rather than zero-copy memory registrations. The memory buffers passed as Addr are borrowed by the kernel for the duration of the asynchronous operation. User code must ensure buffers remain valid, unmoved, and unfreed until the corresponding completion event (CQE) has been reaped.
uring::close(ring) immediately unmaps the ring buffers and closes the kernel file descriptor. Rings must not be closed while operations referencing user buffers remain outstanding.
61.4.3 Completion queue results
Completed operations report kernel status in CQE.res: - Success: Non-negative value (res >= 0), such as the number of bytes transferred. - Error: Negative value (res < 0), matching the negative Linux errno (for example, -62 for -ETIME on timeout expiration, or -125 for -ECANCELED).
61.5 Example
#use io
#use uring
ring_res = uring::new(8)
ring_res
| ring =>
uring::prep_nop(ring, 100)
uring::submit(ring)
cqe_opt = uring::wait_cqe(ring)
cqe_opt
| cqe => io::out(cqe.user_data)
uring::close(ring)