SaneCppAsync.h is a multi-platform / event-driven asynchronous I/O library.
Note: Check library_async_streams for an higher level construct when streaming data
Note: Check library_await for the C++20 coroutine layer that wraps
AsyncEventLoopwithco_awaitsyntax while preserving the same request lifetime expectations. It currently covers a small but useful subset of timers, sockets, loop wake-ups, files, file readiness, selected filesystem operations, process exit, signals, background work, child tasks, task groups, cancellation, and timeouts.
Note:
Awaitkeeps the same platform caveats asAsync: POSIX file readiness is exposed directly, while Windows file readiness for normal file or pipe handles currently fails fast at the Await layer instead of pretending to be portable. File and filesystem operations that need blocking work use caller-providedThreadPoolstorage.
Note: Long-lived callback streams such as
FileSystemWatchershould stay callback-style or use an explicit caller-owned adapter with bounded event storage.Awaitintentionally does not model watcher streams as directAwaitEventLoopmethods.
Dependencies
- Dependencies: File, FileSystem, Socket, Threading
- All dependencies: File, FileSystem, Socket, Threading
Features
This is the list of supported async operations:
| Async Operation | Description |
|---|---|
| AsyncSocketConnect | SC::AsyncSocketConnect |
| AsyncSocketAccept | SC::AsyncSocketAccept |
| AsyncSocketSend | SC::AsyncSocketSend |
| AsyncSocketReceive | SC::AsyncSocketReceive |
| AsyncSocketSendTo | SC::AsyncSocketSendTo |
| AsyncSocketReceiveFrom | SC::AsyncSocketReceiveFrom |
| AsyncFileRead | SC::AsyncFileRead |
| AsyncFileWrite | SC::AsyncFileWrite |
| AsyncLoopTimeout | SC::AsyncLoopTimeout |
| AsyncLoopWakeUp | SC::AsyncLoopWakeUp |
| AsyncLoopWork | SC::AsyncLoopWork |
| AsyncProcessExit | SC::AsyncProcessExit |
| AsyncFileReadiness | SC::AsyncFileReadiness |
| AsyncExternalCompletion | SC::AsyncExternalCompletion |
| AsyncSequence | SC::AsyncSequence |
| AsyncFileSystemOperation | SC::AsyncFileSystemOperation |
| AsyncSignal | SC::AsyncSignal |
Details
Status
MVP This is usable but needs some more testing and a few more features.
Videos
This is the list of videos that have been recorded showing some of the internal thoughts that have been going into this library:
- Ep.07 - SC::Async Linux epoll 1/2
- Ep.08 - SC::Async Linux epoll 2/2
- Ep.10 - A Tour of SC::Async
- Ep.11 - Linux Async I/O using io_uring (1 of 2)
- Ep.12 - Linux Async I/O using io_uring (2 of 2)
- Ep.14 - Async file read and writes using Thread Pool
- Ep.16 - Implement SC::AsyncLoopWork
- Ep.18 - BREAK SC::Async IO Event Loop
- Ep.20 - Pause Immediate Mode UI - Save CPU Time
- Ep.21 - Add Async IO to Immediate Mode GUI
Blog
Some relevant blog posts are:
- April 2024 Update
- May 2024 Update
- June 2024 Update
- July 2024 Update
- August 2024 Update
- December 2024 Update
- January 2025 Update
- April 2025 Update
- May 2025 Update
- June 2025 Update
- July 2025 Update
- August 2025 Update
- November 2025 Update
- December 2025 Update
- January 2026 Update
- February 2026 Update
- March 2026 Update
- May 2026 Update
- March 2026 Update
- May 2026 Update
Description
AsyncEventLoop
Run modes
Event loop can be run in different ways to allow integrated it in multiple ways in applications.
| Run mode | Description |
|---|---|
| SC::AsyncEventLoop::run | SC::AsyncEventLoop::run |
| SC::AsyncEventLoop::runOnce | SC::AsyncEventLoop::runOnce |
| SC::AsyncEventLoop::runNoWait | SC::AsyncEventLoop::runNoWait |
Alternatively user can explicitly use three methods to submit, poll and dispatch events. This is very useful to integrate the event loop into applications with other event loops (for example GUI applications).
| Run mode | Description |
|---|---|
| SC::AsyncEventLoop::submitRequests | SC::AsyncEventLoop::submitRequests |
| SC::AsyncEventLoop::blockingPoll | SC::AsyncEventLoop::blockingPoll |
| SC::AsyncEventLoop::dispatchCompletions | SC::AsyncEventLoop::dispatchCompletions |
AsyncEventLoopMonitor
| Functions | Description |
|---|---|
| SC::AsyncEventLoopMonitor::startMonitoring | SC::AsyncEventLoopMonitor::startMonitoring |
| SC::AsyncEventLoopMonitor::stopMonitoringAndDispatchCompletions | SC::AsyncEventLoopMonitor::stopMonitoringAndDispatchCompletions |
AsyncLoopTimeout
AsyncLoopWakeUp
AsyncLoopWork
AsyncProcessExit
AsyncSignal
AsyncSocketAccept
AsyncSocketConnect
AsyncSocketSend
AsyncSocketReceive
AsyncSocketSendTo
AsyncSocketReceiveFrom
AsyncFileRead
AsyncFileWrite
When using offsets, prefer a single contiguous buffer for portable examples and higher-level helpers. Combining scatter/gather buffers with an explicit offset needs backend-specific validation before being treated as a portable idiom.
AsyncFileReadiness
AsyncExternalCompletion
AsyncSequence
AsyncTaskSequence
AsyncFileSystemOperation
Implementation
Library abstracts async operations by exposing a completion based mechanism.
This mechanism currently maps on kqueue on macOS and OVERLAPPED on Windows.
On Linux it tries to create a direct io_uring backend first and falls back to epoll when the kernel or runtime policy does not allow it.
No liburing shared library is required.
The api works on file and socket descriptors, that can be obtained from the File and Socket libraries. It also works with serial descriptors from SerialPort, by using AsyncFileRead and AsyncFileWrite on an opened SC::SerialDescriptor. Pipe endpoints accepted/connected through SC::NamedPipeServer and SC::NamedPipeClient, exposed as SC::PipeDescriptor are also supported.
On Windows, AsyncTest includes an optional real COM section named serial com0com read/write.
Set SC_TEST_COM0COM_PORT_A and SC_TEST_COM0COM_PORT_B (values can be COMx or \\.\COMx) to enable it.
When variables are unset, this section prints a skip message and succeeds.
Memory allocation
The entire library is free of allocations, as it uses a double linked list inside SC::AsyncRequest.
Caller is responsible for keeping AsyncRequest-derived objects memory stable until async callback is called.
SC::ArenaMap from the Containers can be used to preallocate a bounded pool of Async objects.
Roadmap
Usable Features:
- More AsyncFileSystemOperations
- Async DNS Resolution
Complete Features:
- TTY with ANSI Escape Codes
- Signal handling (multi-watcher, cross-platform)
Statistics
| Type | Lines Of Code | Comments | Sum |
|---|---|---|---|
| Headers | 885 | 830 | 1715 |
| Sources | 6443 | 1454 | 7897 |
| Sum | 7328 | 2284 | 9612 |