/* uring.h — io_uring lifecycle (the kernel-facing seam, part 2). * * Thin ownership wrapper over liburing so the rest of the engine never calls * io_uring_* directly — that keeps the "Linux-only now, portable later" seam * intact (a future epoll/kqueue backend implements the same reactor contract). * Each reactor thread owns exactly one naut_ring for both network and disk. */ #ifndef NAUT_URING_H #define NAUT_URING_H #include "naut/common.h" #include "naut/buf.h" #include typedef struct naut_ring { struct io_uring ring; bool sqpoll; bool send_zc; bool msg_ring; bool buffers_registered; bool recv_fixed; } naut_ring; /* entries: SQ depth (rounded up to a power of two by the kernel). * sqpoll: dedicate a kernel thread to submission polling — removes the * io_uring_enter syscall from the hot path once the queue is warm (needs * CAP_SYS_NICE or /proc/sys tuning on some setups; falls back if it can't). */ naut_err naut_ring_init(naut_ring *r, unsigned entries, bool sqpoll); naut_err naut_ring_init_cpu(naut_ring *r, unsigned entries, bool sqpoll, int sqpoll_cpu); void naut_ring_close(naut_ring *r); /* Detect kernel support for the features the data path relies on. Logs a * summary; returns NAUT_ERR_NOSYS if a hard requirement is missing. */ naut_err naut_ring_probe(naut_ring *r); /* Register the pool's contiguous slab as fixed buffer index 0. Registration * may fail under a low RLIMIT_MEMLOCK; callers can continue in degraded mode. */ naut_err naut_ring_register_bufpool(naut_ring *r, const naut_bufpool *pool); void naut_ring_unregister_buffers(naut_ring *r); /* Prepare a send using SEND_ZC when supported and requested, otherwise normal * SEND. Returns true when the caller must retain the buffer until a CQE with * IORING_CQE_F_NOTIF arrives. */ bool naut_ring_prep_send(naut_ring *r, struct io_uring_sqe *sqe, int fd, const void *buf, size_t len, int flags, bool prefer_zero_copy); /* Returns true when this recv was armed against the registered fixed buffer. * Some kernels accept READ_FIXED but reject IORING_RECVSEND_FIXED_BUF on plain * recv with -EINVAL; the caller should remember this per-operation so it can * distinguish "fixed-buffer unsupported, retry unfixed" from a real error * (rather than tearing the connection down). */ bool naut_ring_prep_recv(naut_ring *r, struct io_uring_sqe *sqe, int fd, void *buf, size_t len, int flags); #endif /* NAUT_URING_H */