• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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