eve.aio.linux.io

Async file I/O primitives for Linux with io_uring optimization.

This module provides a Linux-specific implementation of asynchronous file I/O that uses io_uring when available for true kernel-level async operations. When io_uring is not available (Linux < 5.1 or restricted environments), it falls back to a thread pool implementation.

io_uring benefits for file I/O:

  • True kernel-level async - no threads needed
  • Zero syscall overhead with submission queue batching
  • Works with regular files unlike epoll

Types 11

File operation configuration.

Fields
size_t bufferSizeBuffer size hint for I/O operations.
Methods
bool isValid() @property const pure @safe nothrow @nogcValidate the config.
aliasReadCallback = void delegate(ref AsyncFile file, ubyte[] data, int error) @safe

Callback invoked when a read operation completes. data is a borrowed slice valid only during callback execution.

aliasWriteCallback = void delegate(ref AsyncFile file, size_t bytesWritten, int error) @safe

Callback invoked when a write operation completes. bytesWritten is the actual bytes written (not queued).

aliasErrorCallback = void delegate(ref AsyncFile file, int error) @safe

Callback invoked on error conditions.

structAsyncFile

Async file handle wrapper.

Wraps a file descriptor and integrates with the Layer 1 event loop for async read/write operations. On Linux 5.1+, uses io_uring for true kernel-level async. Falls back to thread pool on older kernels.

Fields
private AsyncFileState _state
Methods
AsyncFile create(FileConfig config = FileConfig.init) static @trustedCreate a detached file wrapper.
void onRead(ReadCallback callback) @safeRegister callback for read completion.
void onWrite(WriteCallback callback) @safeRegister callback for write completion.
void onError(ErrorCallback callback) @safeRegister callback for error conditions.
bool isOpen() @property const @safe nothrow @nogcCheck if the file is open.
FileState state() @property const @safe nothrow @nogcGet the current file state.
bool usingIoUring() @property const @safe nothrow @nogcCheck if this file is using io_uring for async operations.
OpenResult open(ref EventLoop loop, scope const(char)[] path, int flags) @trustedOpen a file for reading and/or writing.
FileResult read(ubyte[] buffer, ulong offset) @trustedQueue an async read operation.
FileResult write(scope const(ubyte)[] data, ulong offset) @trustedQueue an async write operation.
long size() @trustedQuery the file size.
void close() @trustedClose the file.
void dispose() @trustedDispose the file wrapper and release resources.
private AsyncFileState mutableState() @trusted
private enumOperationType : ubyte
NONE
READ
WRITE
private classAsyncFileState
Fields
FileConfig _config
Handle _handle
FileState _fileState
EventLoop * _loop
Token _wakeupToken
Token _ioToken
bool _usingIoUring
OperationType _pendingOp
ubyte[] _readBuffer
ubyte[] _writeDataCopy
int _resultError
size_t _resultBytes
Methods
bool isOpen() @property const @safe nothrow @nogc
bool usingIoUring() @property const @safe nothrow @nogc
OpenResult open(ref EventLoop loop, scope const(char)[] path, int flags) @trusted nothrow
FileResult read(ubyte[] buffer, ulong offset) @trusted
FileResult write(scope const(ubyte)[] data, ulong offset) @trusted
private FileResult submitIoUringRead(ubyte[] buffer, ulong offset) @trusted
private FileResult submitIoUringWrite(scope const(ubyte)[] data, ulong offset) @trusted
private FileResult submitThreadPoolRead(ubyte[] buffer, ulong offset) @trusted
private FileResult submitThreadPoolWrite(scope const(ubyte)[] data, ulong offset) @trusted
long size() @trusted nothrow
void closeFile() @trusted nothrow
void dispose() @trusted nothrow
void handleThreadPoolWakeup(ref EventLoop loop, Token token) @safe nothrow
void invokeReadCallback(int error, size_t bytes) @safe nothrow
void invokeWriteCallback(int error, size_t bytes) @safe nothrow
void notifyComplete(int error, size_t bytes) @trusted nothrow
AsyncFile owner() @trusted nothrow
Constructors

Shared io_uring instance for file I/O operations.

One ring per EventLoop, shared across all AsyncFile instances on that loop. Eliminates per-file ring overhead (mmap, eventfd, kernel state) and amortises io_uring_enter() syscalls across multiple concurrent file operations.

Access via sharedFileRing.

Fields
private int _eventFd
private bool _valid
private void * _sqRing
private void * _cqRing
private void * _sqes
private size_t _sqRingSize
private size_t _cqRingSize
private size_t _sqesSize
private uint _sqEntries
private uint _cqEntries
private shared(uint) * _sqHead
private shared(uint) * _sqTail
private shared(uint) * _sqMask
private shared(uint) * _sqArray
private shared(uint) * _cqHead
private shared(uint) * _cqTail
private shared(uint) * _cqMask
private io_uring_cqe * _cqes
private io_uring_sqe * _sqeArray
private int _ringFd
private bool _probed
private bool _available
Methods
private uint load(shared(uint) * ptr) static @trusted nothrow @nogc
private void store(shared(uint) * ptr, uint value) static @trusted nothrow @nogc
bool isValid() @property const @safe nothrow @nogcWhether this ring is usable for I/O.
int eventFd() @property const @safe nothrow @nogcFile descriptor of the completion eventfd.
bool isAvailable() static @trusted nothrowWhether io_uring is available on this kernel.
IoUringFileRing create(uint entries = SHARED_RING_ENTRIES) static @trusted nothrowCreate a shared io_uring ring.
void dispose() @trusted nothrowRelease all ring resources.
bool submitRead(int fd, void * buf, uint len, ulong offset, ulong userData) @trusted nothrowSubmit a read operation to the ring.
bool submitWrite(int fd, const(void) * buf, uint len, ulong offset, ulong userData) @trusted nothrowSubmit a write operation to the ring.
bool submitClose(int fd, ulong userData) @trusted nothrowSubmit a close operation to the ring.
bool submitSendfile(int sockfd, int fileFd, ulong offset, size_t length, ulong userData) @trusted nothrowSubmit a sendfile-compatible splice if supported.
void processCompletions(scope CompletionCallback callback) @trusted nothrowProcess all available completions.
private bool submitOp(int fd, void * buf, uint len, ulong offset, ulong userData, ubyte opcode) @trusted nothrow
private void initRing(uint entries) @trusted nothrow
private void cleanup() @trusted nothrow @nogc
Constructors
this(uint entries)
private enumThreadPoolWorkType : ubyte
READ
WRITE
private structThreadPoolWorkItem
Fields
int fd
ubyte * buffer
size_t length
ulong offset
private classFileThreadPool

Simple thread pool for file I/O operations (fallback when io_uring unavailable).

Fields
private Mutex _mutex
private Condition _condition
private ThreadPoolWorkItem[] _queue
private Thread _worker
private bool _shutdown
private FileThreadPool _instance
private bool _instanceCreated
Methods
FileThreadPool instance() static @trusted nothrow
void submit(ThreadPoolWorkItem item) @trusted nothrow
private void workerLoop() @trusted nothrow
private void processWork(ref ThreadPoolWorkItem item) @trusted nothrow
Constructors

Functions 11

private fnOpenResult mapOpenError(int err) pure @safe nothrow @nogcMap errno values to OpenResult variants.
private fnvoid sharedRingIoCallback(ref EventLoop loop, Token token, IoReady ready) nothrow
private fnsize_t loopKey(EventLoop * loop) @trusted nothrow @nogc pure
fnIoUringFileRing sharedFileRing(EventLoop * loop) @trusted nothrow
fnvoid disposeSharedFileRing(EventLoop * loop) @trusted nothrow
fnToken sharedFileRingToken(EventLoop * loop) @trusted nothrow
fnvoid sharedFileRingToken(EventLoop * loop, Token token) @trusted nothrow
fnvoid sharedFileRingRetain(EventLoop * loop) @trusted nothrow
fnvoid sharedFileRingRelease(EventLoop * loop) @trusted nothrow
fnuint sharedFileRingUseCount(EventLoop * loop) @trusted nothrow
private fnFileConfig validated(FileConfig config) pure @safe nothrow @nogc

Variables 6

private enumvarO_CLOEXEC = 0x80000

O_CLOEXEC for exec-safe file descriptors.

private enumvarFILE_RING_ENTRIES = 64u

Requested ring size for file I/O operations.

private enumvarSHARED_RING_ENTRIES = 256u

Shared ring SQE count — one ring per EventLoop, large enough for many concurrent file ops.

private varIoUringFileRing[size_t] _sharedRings
private varToken[size_t] _sharedRingTokens
private varuint[size_t] _sharedRingRefCount