Expand description
§giong
A thread-per-core async runtime for Linux, built directly on io_uring.
Named after Thánh Gióng, the child of Vietnamese legend who lay silent for three years and then rose a giant: giong costs next to nothing while idle and uses every core the moment load arrives.
§Design
- Thread-per-core, shared-nothing. Every worker thread owns its own
io_uring, task queue, timers and buffer pool. Tasks never migrate, so
futures need not be
Sendand the hot path has no locks and no atomics beyond a waker flag. - Completion-based I/O with batching. Everything a tick produces —
reads, writes, accepts, closes, cancellations — reaches the kernel in a
single
io_uring_enter, which also returns every completion that is ready. - Multishot accept and receive with kernel-provided buffers: one submission per listener / connection, no buffer pinned by idle connections.
- One ring for everything. TCP, UDP and Unix sockets (
net) and files (fs) all go through the worker’s io_uring. File I/O needs no pool of blocking threads. - A latency dial.
Builder::spin_before_parklets a worker watch its ring instead of sleeping, for services where microseconds matter more than an idle core. - Cancellation safety. Dropping an I/O future never frees memory the kernel may still write to; ownership of the buffer moves to the driver until the kernel confirms.
§Example
use giong::net::TcpListener;
fn main() -> std::io::Result<()> {
giong::Builder::new().shutdown_on_signals(true).build()?.run(|_worker| async {
let listener = TcpListener::bind("0.0.0.0:8080").expect("bind");
while let Some(Ok(stream)) = giong::until_shutdown(listener.accept()).await {
giong::spawn(async move {
loop {
let Ok(data) = stream.recv().await else { return };
if data.is_empty() {
return; // peer closed
}
let reply = data.to_vec();
drop(data); // give the buffer back to the pool
if stream.write_all(reply).await.0.is_err() {
return;
}
}
});
}
})
}§Requirements
Linux 6.0 or newer (6.1+ recommended). giong does not build on other platforms.
Modules§
- fs
- Files on io_uring.
- net
- TCP, UDP and Unix sockets on io_uring.
- sync
- Message passing between tasks — on the same worker, across workers, or from threads outside the runtime.
- time
- Timers:
sleep,sleep_untilandtimeout.
Structs§
- Builder
- Configures and starts a runtime.
- Handle
- A cloneable, thread-safe handle to a runtime.
- Join
Handle - A handle to a spawned task. Awaiting it yields the task’s output.
- RecvBuf
- Bytes received by
TcpStream::recv. - Runtime
- A configured, not yet running, thread-per-core runtime.
- Shutdown
Signal - Future returned by
shutdown_signal.
Enums§
- Join
Error - Why a task did not produce a value.
Traits§
- IoBuf
- A buffer that can be handed to the kernel for the duration of a write.
- IoBuf
Mut - A buffer the kernel may write into (see
IoBuffor the ownership model).
Functions§
- block_
on - Runs a future to completion on the current thread with a single-worker runtime using the default configuration.
- handle
- A handle to the runtime the current task is running on.
- is_
shutting_ down trueonceshutdown_signalwould resolve on the current worker: a shutdown has been requested, or the worker is draining its remaining tasks. A cheap check for loops that are busy rather than waiting.- shutdown_
signal - Resolves once a shutdown of the current runtime has been requested, via
Handle::shutdownor a signal (seeBuilder::shutdown_on_signals), or once the current worker’s main future has completed and the worker is draining its remaining tasks (seeBuilder::shutdown_grace). - spawn
- Spawns a task onto the current worker thread.
- until_
shutdown - Runs
futuntil it completes or a shutdown is requested, whichever comes first. ReturnsNoneif the shutdown won. - worker_
id - Index of the worker the current task is running on (
0..workers). - yield_
now - Yields to the executor, letting other tasks and pending I/O make progress.