spawn.qbk 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. [/
  2. / Copyright (c) 2003-2019 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. [section:spawn Stackful Coroutines]
  8. The [link boost_asio.reference.spawn `spawn()`] function is a high-level wrapper for
  9. running stackful coroutines. It is based on the Boost.Coroutine library. The
  10. `spawn()` function enables programs to implement asynchronous logic in a
  11. synchronous manner, as shown in the following example:
  12. boost::asio::spawn(my_strand, do_echo);
  13. // ...
  14. void do_echo(boost::asio::yield_context yield)
  15. {
  16. try
  17. {
  18. char data[128];
  19. for (;;)
  20. {
  21. std::size_t length =
  22. my_socket.async_read_some(
  23. boost::asio::buffer(data), yield);
  24. boost::asio::async_write(my_socket,
  25. boost::asio::buffer(data, length), yield);
  26. }
  27. }
  28. catch (std::exception& e)
  29. {
  30. // ...
  31. }
  32. }
  33. The first argument to `spawn()` may be a
  34. [link boost_asio.reference.io_context__strand `strand`],
  35. [link boost_asio.reference.io_context `io_context`], or
  36. [link boost_asio.reference.CompletionHandler completion handler].
  37. This argument determines the context in which the coroutine is permitted to
  38. execute. For example, a server's per-client object may consist of multiple
  39. coroutines; they should all run on the same `strand` so that no explicit
  40. synchronisation is required.
  41. The second argument is a function object with signature:
  42. void coroutine(boost::asio::yield_context yield);
  43. that specifies the code to be run as part of the coroutine. The parameter
  44. `yield` may be passed to an asynchronous operation in place of the completion
  45. handler, as in:
  46. std::size_t length =
  47. my_socket.async_read_some(
  48. boost::asio::buffer(data), yield);
  49. This starts the asynchronous operation and suspends the coroutine. The
  50. coroutine will be resumed automatically when the asynchronous operation
  51. completes.
  52. Where an asynchronous operation's handler signature has the form:
  53. void handler(boost::system::error_code ec, result_type result);
  54. the initiating function returns the result_type. In the `async_read_some`
  55. example above, this is `size_t`. If the asynchronous operation fails, the
  56. `error_code` is converted into a `system_error` exception and thrown.
  57. Where a handler signature has the form:
  58. void handler(boost::system::error_code ec);
  59. the initiating function returns `void`. As above, an error is passed back to
  60. the coroutine as a `system_error` exception.
  61. To collect the `error_code` from an operation, rather than have it throw an
  62. exception, associate the output variable with the `yield_context` as follows:
  63. boost::system::error_code ec;
  64. std::size_t length =
  65. my_socket.async_read_some(
  66. boost::asio::buffer(data), yield[ec]);
  67. [*Note:] if `spawn()` is used with a custom completion handler of type
  68. `Handler`, the function object signature is actually:
  69. void coroutine(boost::asio::basic_yield_context<Handler> yield);
  70. [heading See Also]
  71. [link boost_asio.reference.spawn spawn],
  72. [link boost_asio.reference.yield_context yield_context],
  73. [link boost_asio.reference.basic_yield_context basic_yield_context],
  74. [link boost_asio.examples.cpp03_examples.spawn Spawn example (C++03)],
  75. [link boost_asio.examples.cpp11_examples.spawn Spawn example (C++11)],
  76. [link boost_asio.overview.core.coroutine Stackless Coroutines].
  77. [endsect]