baca9a092f
The awaitable<>, co_spawn(), this_coro, detached, and redirect_error facilities have been moved from the asio::experimental namespace to namespace asio. As part of this change, the this_coro::token() awaitable has been superseded by the asio::use_awaitable completion token. Please note that the use_awaitable and redirect_error completion tokens work only with asynchronous operations that use the new form of async_result with member function initiate(). Furthermore, when using use_awaitable, please be aware that the asynchronous operation is not initiated until co_await is applied to the awaitable<>.
98 lines
3.9 KiB
Plaintext
98 lines
3.9 KiB
Plaintext
[/
|
|
/ Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
|
/
|
|
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
/]
|
|
|
|
[section:coroutines_ts Coroutines TS Support]
|
|
|
|
Support for the Coroutines TS is provided via the [link
|
|
boost_asio.reference.awaitable `awaitable`] class template, the [link
|
|
boost_asio.reference.use_awaitable_t `use_awaitable`] completion token, and the [link
|
|
boost_asio.reference.co_spawn `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 [link boost_asio.reference.Executor1
|
|
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 [link
|
|
boost_asio.reference.awaitable `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, [link
|
|
boost_asio.reference.detached `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.
|
|
|
|
[heading See Also]
|
|
|
|
[link boost_asio.reference.co_spawn co_spawn],
|
|
[link boost_asio.reference.detached detached],
|
|
[link boost_asio.reference.redirect_error redirect_error],
|
|
[link boost_asio.reference.awaitable awaitable],
|
|
[link boost_asio.reference.use_awaitable_t use_awaitable_t],
|
|
[link boost_asio.reference.use_awaitable use_awaitable],
|
|
[link boost_asio.reference.this_coro__executor this_coro::executor],
|
|
[link boost_asio.examples.cpp17_examples.coroutines_ts_support Coroutines TS examples],
|
|
[link boost_asio.overview.core.spawn Stackful Coroutines],
|
|
[link boost_asio.overview.core.coroutine Stackless Coroutines].
|
|
|
|
[endsect]
|