Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/asio/spawn.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // | |
2 // spawn.hpp | |
3 // ~~~~~~~~~ | |
4 // | |
5 // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) | |
6 // | |
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 // | |
10 | |
11 #ifndef BOOST_ASIO_SPAWN_HPP | |
12 #define BOOST_ASIO_SPAWN_HPP | |
13 | |
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 # pragma once | |
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | |
18 #include <boost/asio/detail/config.hpp> | |
19 #include <boost/coroutine/coroutine.hpp> | |
20 #include <boost/asio/detail/weak_ptr.hpp> | |
21 #include <boost/asio/detail/wrapped_handler.hpp> | |
22 #include <boost/asio/io_service.hpp> | |
23 #include <boost/asio/strand.hpp> | |
24 | |
25 #include <boost/asio/detail/push_options.hpp> | |
26 | |
27 namespace boost { | |
28 namespace asio { | |
29 | |
30 /// Context object the represents the currently executing coroutine. | |
31 /** | |
32 * The basic_yield_context class is used to represent the currently executing | |
33 * stackful coroutine. A basic_yield_context may be passed as a handler to an | |
34 * asynchronous operation. For example: | |
35 * | |
36 * @code template <typename Handler> | |
37 * void my_coroutine(basic_yield_context<Handler> yield) | |
38 * { | |
39 * ... | |
40 * std::size_t n = my_socket.async_read_some(buffer, yield); | |
41 * ... | |
42 * } @endcode | |
43 * | |
44 * The initiating function (async_read_some in the above example) suspends the | |
45 * current coroutine. The coroutine is resumed when the asynchronous operation | |
46 * completes, and the result of the operation is returned. | |
47 */ | |
48 template <typename Handler> | |
49 class basic_yield_context | |
50 { | |
51 public: | |
52 /// The coroutine callee type, used by the implementation. | |
53 /** | |
54 * When using Boost.Coroutine v1, this type is: | |
55 * @code typename coroutine<void()> @endcode | |
56 * When using Boost.Coroutine v2 (unidirectional coroutines), this type is: | |
57 * @code push_coroutine<void> @endcode | |
58 */ | |
59 #if defined(GENERATING_DOCUMENTATION) | |
60 typedef implementation_defined callee_type; | |
61 #elif defined(BOOST_COROUTINES_UNIDRECT) || defined(BOOST_COROUTINES_V2) | |
62 typedef boost::coroutines::push_coroutine<void> callee_type; | |
63 #else | |
64 typedef boost::coroutines::coroutine<void()> callee_type; | |
65 #endif | |
66 | |
67 /// The coroutine caller type, used by the implementation. | |
68 /** | |
69 * When using Boost.Coroutine v1, this type is: | |
70 * @code typename coroutine<void()>::caller_type @endcode | |
71 * When using Boost.Coroutine v2 (unidirectional coroutines), this type is: | |
72 * @code pull_coroutine<void> @endcode | |
73 */ | |
74 #if defined(GENERATING_DOCUMENTATION) | |
75 typedef implementation_defined caller_type; | |
76 #elif defined(BOOST_COROUTINES_UNIDRECT) || defined(BOOST_COROUTINES_V2) | |
77 typedef boost::coroutines::pull_coroutine<void> caller_type; | |
78 #else | |
79 typedef boost::coroutines::coroutine<void()>::caller_type caller_type; | |
80 #endif | |
81 | |
82 /// Construct a yield context to represent the specified coroutine. | |
83 /** | |
84 * Most applications do not need to use this constructor. Instead, the | |
85 * spawn() function passes a yield context as an argument to the coroutine | |
86 * function. | |
87 */ | |
88 basic_yield_context( | |
89 const detail::weak_ptr<callee_type>& coro, | |
90 caller_type& ca, Handler& handler) | |
91 : coro_(coro), | |
92 ca_(ca), | |
93 handler_(handler), | |
94 ec_(0) | |
95 { | |
96 } | |
97 | |
98 /// Return a yield context that sets the specified error_code. | |
99 /** | |
100 * By default, when a yield context is used with an asynchronous operation, a | |
101 * non-success error_code is converted to system_error and thrown. This | |
102 * operator may be used to specify an error_code object that should instead be | |
103 * set with the asynchronous operation's result. For example: | |
104 * | |
105 * @code template <typename Handler> | |
106 * void my_coroutine(basic_yield_context<Handler> yield) | |
107 * { | |
108 * ... | |
109 * std::size_t n = my_socket.async_read_some(buffer, yield[ec]); | |
110 * if (ec) | |
111 * { | |
112 * // An error occurred. | |
113 * } | |
114 * ... | |
115 * } @endcode | |
116 */ | |
117 basic_yield_context operator[](boost::system::error_code& ec) const | |
118 { | |
119 basic_yield_context tmp(*this); | |
120 tmp.ec_ = &ec; | |
121 return tmp; | |
122 } | |
123 | |
124 #if defined(GENERATING_DOCUMENTATION) | |
125 private: | |
126 #endif // defined(GENERATING_DOCUMENTATION) | |
127 detail::weak_ptr<callee_type> coro_; | |
128 caller_type& ca_; | |
129 Handler& handler_; | |
130 boost::system::error_code* ec_; | |
131 }; | |
132 | |
133 #if defined(GENERATING_DOCUMENTATION) | |
134 /// Context object that represents the currently executing coroutine. | |
135 typedef basic_yield_context<unspecified> yield_context; | |
136 #else // defined(GENERATING_DOCUMENTATION) | |
137 typedef basic_yield_context< | |
138 detail::wrapped_handler< | |
139 io_service::strand, void(*)(), | |
140 detail::is_continuation_if_running> > yield_context; | |
141 #endif // defined(GENERATING_DOCUMENTATION) | |
142 | |
143 /** | |
144 * @defgroup spawn boost::asio::spawn | |
145 * | |
146 * @brief Start a new stackful coroutine. | |
147 * | |
148 * The spawn() function is a high-level wrapper over the Boost.Coroutine | |
149 * library. This function enables programs to implement asynchronous logic in a | |
150 * synchronous manner, as illustrated by the following example: | |
151 * | |
152 * @code boost::asio::spawn(my_strand, do_echo); | |
153 * | |
154 * // ... | |
155 * | |
156 * void do_echo(boost::asio::yield_context yield) | |
157 * { | |
158 * try | |
159 * { | |
160 * char data[128]; | |
161 * for (;;) | |
162 * { | |
163 * std::size_t length = | |
164 * my_socket.async_read_some( | |
165 * boost::asio::buffer(data), yield); | |
166 * | |
167 * boost::asio::async_write(my_socket, | |
168 * boost::asio::buffer(data, length), yield); | |
169 * } | |
170 * } | |
171 * catch (std::exception& e) | |
172 * { | |
173 * // ... | |
174 * } | |
175 * } @endcode | |
176 */ | |
177 /*@{*/ | |
178 | |
179 /// Start a new stackful coroutine, calling the specified handler when it | |
180 /// completes. | |
181 /** | |
182 * This function is used to launch a new coroutine. | |
183 * | |
184 * @param handler A handler to be called when the coroutine exits. More | |
185 * importantly, the handler provides an execution context (via the the handler | |
186 * invocation hook) for the coroutine. The handler must have the signature: | |
187 * @code void handler(); @endcode | |
188 * | |
189 * @param function The coroutine function. The function must have the signature: | |
190 * @code void function(basic_yield_context<Handler> yield); @endcode | |
191 * | |
192 * @param attributes Boost.Coroutine attributes used to customise the coroutine. | |
193 */ | |
194 template <typename Handler, typename Function> | |
195 void spawn(BOOST_ASIO_MOVE_ARG(Handler) handler, | |
196 BOOST_ASIO_MOVE_ARG(Function) function, | |
197 const boost::coroutines::attributes& attributes | |
198 = boost::coroutines::attributes()); | |
199 | |
200 /// Start a new stackful coroutine, inheriting the execution context of another. | |
201 /** | |
202 * This function is used to launch a new coroutine. | |
203 * | |
204 * @param ctx Identifies the current coroutine as a parent of the new | |
205 * coroutine. This specifies that the new coroutine should inherit the | |
206 * execution context of the parent. For example, if the parent coroutine is | |
207 * executing in a particular strand, then the new coroutine will execute in the | |
208 * same strand. | |
209 * | |
210 * @param function The coroutine function. The function must have the signature: | |
211 * @code void function(basic_yield_context<Handler> yield); @endcode | |
212 * | |
213 * @param attributes Boost.Coroutine attributes used to customise the coroutine. | |
214 */ | |
215 template <typename Handler, typename Function> | |
216 void spawn(basic_yield_context<Handler> ctx, | |
217 BOOST_ASIO_MOVE_ARG(Function) function, | |
218 const boost::coroutines::attributes& attributes | |
219 = boost::coroutines::attributes()); | |
220 | |
221 /// Start a new stackful coroutine that executes in the context of a strand. | |
222 /** | |
223 * This function is used to launch a new coroutine. | |
224 * | |
225 * @param strand Identifies a strand. By starting multiple coroutines on the | |
226 * same strand, the implementation ensures that none of those coroutines can | |
227 * execute simultaneously. | |
228 * | |
229 * @param function The coroutine function. The function must have the signature: | |
230 * @code void function(yield_context yield); @endcode | |
231 * | |
232 * @param attributes Boost.Coroutine attributes used to customise the coroutine. | |
233 */ | |
234 template <typename Function> | |
235 void spawn(boost::asio::io_service::strand strand, | |
236 BOOST_ASIO_MOVE_ARG(Function) function, | |
237 const boost::coroutines::attributes& attributes | |
238 = boost::coroutines::attributes()); | |
239 | |
240 /// Start a new stackful coroutine that executes on a given io_service. | |
241 /** | |
242 * This function is used to launch a new coroutine. | |
243 * | |
244 * @param io_service Identifies the io_service that will run the coroutine. The | |
245 * new coroutine is implicitly given its own strand within this io_service. | |
246 * | |
247 * @param function The coroutine function. The function must have the signature: | |
248 * @code void function(yield_context yield); @endcode | |
249 * | |
250 * @param attributes Boost.Coroutine attributes used to customise the coroutine. | |
251 */ | |
252 template <typename Function> | |
253 void spawn(boost::asio::io_service& io_service, | |
254 BOOST_ASIO_MOVE_ARG(Function) function, | |
255 const boost::coroutines::attributes& attributes | |
256 = boost::coroutines::attributes()); | |
257 | |
258 /*@}*/ | |
259 | |
260 } // namespace asio | |
261 } // namespace boost | |
262 | |
263 #include <boost/asio/detail/pop_options.hpp> | |
264 | |
265 #include <boost/asio/impl/spawn.hpp> | |
266 | |
267 #endif // BOOST_ASIO_SPAWN_HPP |