Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of boost. Click here for the latest Boost documentation.
PrevUpHomeNext

Coroutines TS Support

Support for the Coroutines TS is provided via the awaitable class template, the use_awaitable completion token, and the co_spawn() function. These facilities allow programs to implement asynchronous logic in a synchronous manner, in conjunction with the co_await keyword, as shown in the following example:

boost::asio::co_spawn(executor,
    [socket = std::move(socket)]() mutable
    {
      return echo(std::move(socket));
    },
    boost::asio::detached);

// ...

boost::asio::awaitable<void> echo(tcp::socket socket)
{
  try
  {
    char data[1024];
    for (;;)
    {
      std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);
      co_await async_write(socket, boost::asio::buffer(data, n), boost::asio::use_awaitable);
    }
  }
  catch (std::exception& e)
  {
    std::printf("echo Exception: %s\n", e.what());
  }
}

The first argument to co_spawn() is an executor that determines the context in which the coroutine is permitted to execute. For example, a server's per-client object may consist of multiple coroutines; they should all run on the same strand so that no explicit synchronisation is required.

The second argument is a nullary function object that returns a boost::asio::awaitable<R>, where R is the type of return value produced by the coroutine. In the above example, the coroutine returns void.

The third argument is a completion token, and this is used by co_spawn() to produce a completion handler with signature void(std::exception_ptr, R). This completion handler is invoked with the result of the coroutine once it has finished. In the above example we pass a completion token type, boost::asio::detached, which is used to explicitly ignore the result of an asynchronous operation.

In this example the body of the coroutine is implemented in the echo function. When the use_awaitable completion token is passed to an asynchronous operation, the operation's initiating function returns an awaitable that may be used with the co_await keyword:

std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable);

Where an asynchronous operation's handler signature has the form:

void handler(boost::system::error_code ec, result_type result);

the resulting type of the co_await expression is result_type. In the async_read_some example above, this is size_t. If the asynchronous operation fails, the error_code is converted into a system_error exception and thrown.

Where a handler signature has the form:

void handler(boost::system::error_code ec);

the co_await expression produces a void result. As above, an error is passed back to the coroutine as a system_error exception.

See Also

co_spawn, detached, redirect_error, awaitable, use_awaitable_t, use_awaitable, this_coro::executor, Coroutines TS examples, Stackful Coroutines, Stackless Coroutines.


PrevUpHomeNext