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