boost · advanced

Boost.Asio: Coroutines with co_await (awaitable)

Callback-based Asio fragments a simple read-then-write loop into nested completion handlers — the classic 'callback hell' — scattering both logic and error handling, so C++20 coroutines combined with Asio's awaitable<T> exist to restore straight-line code. Writing co_await sock.async_read_some(buffer, use_awaitable) suspends the coroutine and releases the thread; when the operation completes the coroutine resumes exactly where it left off with the result in hand, with no nested handler and with errors surfacing as ordinary exceptions you can try/catch (or, using as_tuple or redirect_error, as an error_code). You start a coroutine with co_spawn(executor, coroutine(), token), and because awaitables compose, one coroutine can co_await another; Asio's coroutines are stackless and effectively zero-overhead, making this the modern, recommended style — and it pairs cleanly with strands for safe concurrency.

🔑 Key line

C++20 coroutines + Asio's awaitable<T> replace nested callbacks with linear code: co_await async_*(..., use_awaitable) suspends the coroutine and resumes on completion with the result; errors become exceptions (or use as_tuple/redirect_error). Launch with co_spawn; awaitables compose, are stackless and ~zero-overhead — the modern way to write Asio.

The code

boost::asio::awaitable<void> echo(tcp::socket sock) {
char data[1024];
for (;;) {
std::size_t n = co_await sock.async_read_some(
boost::asio::buffer(data), boost::asio::use_awaitable);
co_await boost::asio::async_write(sock,
boost::asio::buffer(data, n), boost::asio::use_awaitable);
}
}
boost::asio::co_spawn(io, echo(std::move(sock)), boost::asio::detached);

What this lesson walks through

  1. 01Callbacks invert your control flow
  2. 02co_await suspends, then resumes
  3. 03Launch with co_spawn

Pure callback code fragments a simple read→write→read loop into nested handlers — 'callback hell' — where the logic and error handling are scattered. C++20 coroutines plus Asio's awaitable<T> let you write asynchronous code that reads top-to-bottom like synchronous code.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of Boost.Asio: Coroutines with co_await (awaitable) and 100+ animated C++ interview lessons.

← Previous
Boost.Asio: Strands — Lock-Free Handler Serialization
Next →
Boost.Asio: An Async TCP Echo Server