1[/ 2 / Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) 3 / 4 / Distributed under the Boost Software License, Version 1.0. (See accompanying 5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 /] 7 8[section:coroutines_ts Coroutines TS Support] 9 10Support for the Coroutines TS is provided via the [link 11boost_asio.reference.awaitable `awaitable`] class template, the [link 12boost_asio.reference.use_awaitable_t `use_awaitable`] completion token, and the [link 13boost_asio.reference.co_spawn `co_spawn()`] function. These facilities allow programs 14to implement asynchronous logic in a synchronous manner, in conjunction with 15the `co_await` keyword, as shown in the following example: 16 17 boost::asio::co_spawn(executor, echo(std::move(socket)), boost::asio::detached); 18 19 // ... 20 21 boost::asio::awaitable<void> echo(tcp::socket socket) 22 { 23 try 24 { 25 char data[1024]; 26 for (;;) 27 { 28 std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable); 29 co_await async_write(socket, boost::asio::buffer(data, n), boost::asio::use_awaitable); 30 } 31 } 32 catch (std::exception& e) 33 { 34 std::printf("echo Exception: %s\n", e.what()); 35 } 36 } 37 38The first argument to `co_spawn()` is an [link boost_asio.reference.Executor1 39executor] that determines the context in which the coroutine is permitted to 40execute. For example, a server's per-client object may consist of multiple 41coroutines; they should all run on the same `strand` so that no explicit 42synchronisation is required. 43 44The second argument is an [link boost_asio.reference.awaitable `awaitable<R>`], 45that is the result of the coroutine's entry point function, and in the above 46example is the result of the call to `echo`. (Alternatively, this argument can 47be a function object that returns the [link boost_asio.reference.awaitable 48`awaitable<R>`].) The template parameter `R` is the type of return value 49produced by the coroutine. In the above example, the coroutine returns `void`. 50 51The third argument is a completion token, and this is used by `co_spawn()` to 52produce a completion handler with signature `void(std::exception_ptr, R)`. This 53completion handler is invoked with the result of the coroutine once it has 54finished. In the above example we pass a completion token type, [link 55boost_asio.reference.detached `boost::asio::detached`], which is used to explicitly ignore 56the result of an asynchronous operation. 57 58In this example the body of the coroutine is implemented in the `echo` 59function. When the `use_awaitable` completion token is passed to an 60asynchronous operation, the operation's initiating function returns an 61`awaitable` that may be used with the `co_await` keyword: 62 63 std::size_t n = co_await socket.async_read_some(boost::asio::buffer(data), boost::asio::use_awaitable); 64 65Where an asynchronous operation's handler signature has the form: 66 67 void handler(boost::system::error_code ec, result_type result); 68 69the resulting type of the `co_await` expression is `result_type`. In the 70`async_read_some` example above, this is `size_t`. If the asynchronous 71operation fails, the `error_code` is converted into a `system_error` exception 72and thrown. 73 74Where a handler signature has the form: 75 76 void handler(boost::system::error_code ec); 77 78the `co_await` expression produces a `void` result. As above, an error is 79passed back to the coroutine as a `system_error` exception. 80 81[heading See Also] 82 83[link boost_asio.reference.co_spawn co_spawn], 84[link boost_asio.reference.detached detached], 85[link boost_asio.reference.redirect_error redirect_error], 86[link boost_asio.reference.awaitable awaitable], 87[link boost_asio.reference.use_awaitable_t use_awaitable_t], 88[link boost_asio.reference.use_awaitable use_awaitable], 89[link boost_asio.reference.this_coro__executor this_coro::executor], 90[link boost_asio.examples.cpp17_examples.coroutines_ts_support Coroutines TS examples], 91[link boost_asio.overview.core.spawn Stackful Coroutines], 92[link boost_asio.overview.core.coroutine Stackless Coroutines]. 93 94[endsect] 95