Boost.Corosio
Boost.Corosio is a coroutine-first I/O library for C++20 that provides asynchronous networking primitives with automatic executor affinity propagation.
What This Library Does
Corosio provides asynchronous I/O operations designed from the ground up for C++20 coroutines. Every operation returns an awaitable that integrates with the affine awaitable protocol, ensuring your coroutines resume on the correct executor without manual dispatch.
-
io_context — Event loop for processing asynchronous operations
-
socket — Asynchronous TCP socket with connect, read, and write
-
acceptor — TCP listener for accepting incoming connections
-
tcp_server — Server framework with worker pools
-
resolver — Asynchronous DNS resolution
-
timer — Asynchronous timer for delays and timeouts
-
signal_set — Asynchronous signal handling
-
wolfssl_stream — TLS encryption using WolfSSL
What This Library Does Not Do
Corosio focuses on coroutine-first I/O primitives. It does not include:
-
General-purpose executor abstractions (use Boost.Capy)
-
The sender/receiver execution model (P2300)
-
HTTP, WebSocket, or other application protocols (use Boost.Http or Boost.Beast2)
-
UDP or other transport protocols (TCP only for now)
Corosio works with Boost.Capy for task management and execution contexts.
Design Philosophy
Coroutines first. Every I/O operation returns an awaitable. There are no callback-based interfaces.
Affinity through protocol. The dispatcher propagates through await_suspend
parameters, not through thread-local storage. When an I/O operation completes,
it resumes your coroutine through the dispatcher you provided.
Structured bindings. Results use io_result<T> which supports structured
bindings: auto [ec, n] = co_await s.read_some(buf). Call .value() to throw
on error instead.
Type erasure at I/O boundaries. Socket implementations use type-erased dispatchers internally. The indirection cost is negligible compared to I/O latency.
Target Audience
Corosio is designed for C++ developers who want to build network applications using modern asynchronous programming patterns. This documentation assumes:
-
Familiarity with Boost.Capy — task types, executors, buffer sequences
-
Understanding of C++20 coroutines —
co_await,co_return, awaitables -
Basic TCP/IP networking concepts — clients, servers, ports, connections
If you’re new to these topics, see TCP/IP Networking and Concurrent Programming for background.
Code Convention
| Code examples in this documentation assume these declarations are in effect: |
#include <boost/corosio.hpp>
#include <boost/capy/task.hpp>
#include <boost/capy/ex/run_async.hpp>
namespace corosio = boost::corosio;
namespace capy = boost::capy;
Quick Example
#include <boost/corosio.hpp>
#include <boost/capy/task.hpp>
#include <boost/capy/ex/run_async.hpp>
#include <iostream>
namespace corosio = boost::corosio;
namespace capy = boost::capy;
capy::task<void> connect_example(corosio::io_context& ioc)
{
corosio::socket s(ioc);
s.open();
// Connect using structured bindings
auto [ec] = co_await s.connect(
corosio::endpoint(boost::urls::ipv4_address::loopback(), 8080));
if (ec)
{
std::cerr << "Connect failed: " << ec.message() << "\n";
co_return;
}
// Read some data
char buf[1024];
auto [read_ec, n] = co_await s.read_some(
capy::mutable_buffer(buf, sizeof(buf)));
if (!read_ec)
std::cout << "Received " << n << " bytes\n";
}
int main()
{
corosio::io_context ioc;
capy::run_async(ioc.get_executor())(connect_example(ioc));
ioc.run();
}
Next Steps
-
Quick Start — Build a working echo server
-
TCP/IP Networking — Networking fundamentals
-
Concurrent Programming — Coroutines and strands
-
I/O Context — Understand the event loop
-
Sockets — Learn socket operations in detail