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 IoAwaitable protocol, ensuring your coroutines resume on the correct executor without manual dispatch.

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)

  • Raw sockets

Corosio works with Boost.Capy for task management and execution contexts.

Design Philosophy

Coroutines only. Every I/O operation returns an awaitable. There are no callback-based interfaces.

Affinity through protocol. The executor propagates through await_suspend parameters, not through thread-local storage. When an I/O operation completes, it resumes your coroutine through the executor you provided.

Structured bindings. Results use io_result<T> which supports structured bindings: auto [ec, n] = co_await s.read_some(buf). See Error Handling for how to handle the error code.

Type erasure at I/O boundaries. Socket implementations use type-erased I/O backends 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.

Requirements

  • C++20 compiler with coroutine support

  • Boost libraries: Capy

Tested Compilers

  • GCC 12+

  • Clang 17+

  • Apple Clang (latest Xcode on macOS 14, 15, 26)

  • MSVC 14.34+ (Visual Studio 2022 17.4+)

  • Clang-CL (Visual Studio 2022)

  • MinGW (latest)

Platform Support

  • Linux — epoll backend (x86_64, ARM64); io_uring backend available, not the default

  • Windows — IOCP backend

  • macOS — kqueue backend (ARM64)

  • FreeBSD — kqueue backend

  • Linux, macOS, and FreeBSD also support the select backend

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)
{
    // connect() opens the socket automatically
    corosio::tcp_socket s(ioc);

    // Connect using structured bindings
    auto [ec] = co_await s.connect(
        corosio::endpoint(corosio::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