]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/co_spawn.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / co_spawn.hpp
CommitLineData
92f5a8d4
TL
1//
2// co_spawn.hpp
3// ~~~~~~~~~~~~
4//
f67539c2 5// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
92f5a8d4
TL
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_CO_SPAWN_HPP
12#define BOOST_ASIO_CO_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
20#if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
21
22#include <boost/asio/awaitable.hpp>
20effc67 23#include <boost/asio/execution/executor.hpp>
92f5a8d4
TL
24#include <boost/asio/execution_context.hpp>
25#include <boost/asio/is_executor.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31namespace detail {
32
33template <typename T>
34struct awaitable_signature;
35
36template <typename T, typename Executor>
37struct awaitable_signature<awaitable<T, Executor>>
38{
39 typedef void type(std::exception_ptr, T);
40};
41
42template <typename Executor>
43struct awaitable_signature<awaitable<void, Executor>>
44{
45 typedef void type(std::exception_ptr);
46};
47
48} // namespace detail
49
20effc67 50/// Spawn a new coroutined-based thread of execution.
92f5a8d4 51/**
20effc67
TL
52 * @param ex The executor that will be used to schedule the new thread of
53 * execution.
92f5a8d4 54 *
20effc67
TL
55 * @param a The boost::asio::awaitable object that is the result of calling the
56 * coroutine's entry point function.
92f5a8d4 57 *
20effc67
TL
58 * @param token The completion token that will handle the notification that
59 * the thread of execution has completed. The function signature of the
60 * completion handler must be:
61 * @code void handler(std::exception_ptr, T); @endcode
62 *
63 * @par Example
64 * @code
65 * boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
66 * {
67 * std::size_t bytes_transferred = 0;
68 *
69 * try
70 * {
71 * char data[1024];
72 * for (;;)
73 * {
74 * std::size_t n = co_await socket.async_read_some(
75 * boost::asio::buffer(data), boost::asio::use_awaitable);
76 *
77 * co_await boost::asio::async_write(socket,
78 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
79 *
80 * bytes_transferred += n;
81 * }
82 * }
83 * catch (const std::exception&)
84 * {
85 * }
86 *
87 * co_return bytes_transferred;
88 * }
89 *
90 * // ...
91 *
92 * boost::asio::co_spawn(my_executor,
93 * echo(std::move(my_tcp_socket)),
94 * [](std::exception_ptr e, std::size_t n)
95 * {
96 * std::cout << "transferred " << n << "\n";
97 * });
98 * @endcode
99 */
100template <typename Executor, typename T, typename AwaitableExecutor,
101 BOOST_ASIO_COMPLETION_TOKEN_FOR(
102 void(std::exception_ptr, T)) CompletionToken
103 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
104inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
105 CompletionToken, void(std::exception_ptr, T))
106co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a,
107 CompletionToken&& token
108 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
109 typename enable_if<
110 (is_executor<Executor>::value || execution::is_executor<Executor>::value)
111 && is_convertible<Executor, AwaitableExecutor>::value
112 >::type* = 0);
113
114/// Spawn a new coroutined-based thread of execution.
115/**
116 * @param ex The executor that will be used to schedule the new thread of
117 * execution.
118 *
119 * @param a The boost::asio::awaitable object that is the result of calling the
120 * coroutine's entry point function.
121 *
122 * @param token The completion token that will handle the notification that
123 * the thread of execution has completed. The function signature of the
124 * completion handler must be:
125 * @code void handler(std::exception_ptr); @endcode
126 *
127 * @par Example
128 * @code
129 * boost::asio::awaitable<void> echo(tcp::socket socket)
130 * {
131 * try
132 * {
133 * char data[1024];
134 * for (;;)
135 * {
136 * std::size_t n = co_await socket.async_read_some(
137 * boost::asio::buffer(data), boost::asio::use_awaitable);
138 *
139 * co_await boost::asio::async_write(socket,
140 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
141 * }
142 * }
143 * catch (const std::exception& e)
144 * {
145 * std::cerr << "Exception: " << e.what() << "\n";
146 * }
147 * }
148 *
149 * // ...
150 *
151 * boost::asio::co_spawn(my_executor,
152 * echo(std::move(my_tcp_socket)),
153 * boost::asio::detached);
154 * @endcode
155 */
156template <typename Executor, typename AwaitableExecutor,
157 BOOST_ASIO_COMPLETION_TOKEN_FOR(
158 void(std::exception_ptr)) CompletionToken
159 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
160inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
161 CompletionToken, void(std::exception_ptr))
162co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a,
163 CompletionToken&& token
164 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
165 typename enable_if<
166 (is_executor<Executor>::value || execution::is_executor<Executor>::value)
167 && is_convertible<Executor, AwaitableExecutor>::value
168 >::type* = 0);
169
170/// Spawn a new coroutined-based thread of execution.
171/**
172 * @param ctx An execution context that will provide the executor to be used to
173 * schedule the new thread of execution.
174 *
175 * @param a The boost::asio::awaitable object that is the result of calling the
176 * coroutine's entry point function.
177 *
178 * @param token The completion token that will handle the notification that
179 * the thread of execution has completed. The function signature of the
180 * completion handler must be:
181 * @code void handler(std::exception_ptr); @endcode
182 *
183 * @par Example
184 * @code
185 * boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
186 * {
187 * std::size_t bytes_transferred = 0;
188 *
189 * try
190 * {
191 * char data[1024];
192 * for (;;)
193 * {
194 * std::size_t n = co_await socket.async_read_some(
195 * boost::asio::buffer(data), boost::asio::use_awaitable);
196 *
197 * co_await boost::asio::async_write(socket,
198 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
199 *
200 * bytes_transferred += n;
201 * }
202 * }
203 * catch (const std::exception&)
204 * {
205 * }
206 *
207 * co_return bytes_transferred;
208 * }
209 *
210 * // ...
211 *
212 * boost::asio::co_spawn(my_io_context,
213 * echo(std::move(my_tcp_socket)),
214 * [](std::exception_ptr e, std::size_t n)
215 * {
216 * std::cout << "transferred " << n << "\n";
217 * });
218 * @endcode
219 */
220template <typename ExecutionContext, typename T, typename AwaitableExecutor,
221 BOOST_ASIO_COMPLETION_TOKEN_FOR(
222 void(std::exception_ptr, T)) CompletionToken
223 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
224 typename ExecutionContext::executor_type)>
225inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
226 CompletionToken, void(std::exception_ptr, T))
227co_spawn(ExecutionContext& ctx, awaitable<T, AwaitableExecutor> a,
228 CompletionToken&& token
229 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
230 typename ExecutionContext::executor_type),
231 typename enable_if<
232 is_convertible<ExecutionContext&, execution_context&>::value
233 && is_convertible<typename ExecutionContext::executor_type,
234 AwaitableExecutor>::value
235 >::type* = 0);
236
237/// Spawn a new coroutined-based thread of execution.
238/**
239 * @param ctx An execution context that will provide the executor to be used to
240 * schedule the new thread of execution.
241 *
242 * @param a The boost::asio::awaitable object that is the result of calling the
243 * coroutine's entry point function.
244 *
245 * @param token The completion token that will handle the notification that
246 * the thread of execution has completed. The function signature of the
247 * completion handler must be:
248 * @code void handler(std::exception_ptr); @endcode
249 *
250 * @par Example
251 * @code
252 * boost::asio::awaitable<void> echo(tcp::socket socket)
253 * {
254 * try
255 * {
256 * char data[1024];
257 * for (;;)
258 * {
259 * std::size_t n = co_await socket.async_read_some(
260 * boost::asio::buffer(data), boost::asio::use_awaitable);
261 *
262 * co_await boost::asio::async_write(socket,
263 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
264 * }
265 * }
266 * catch (const std::exception& e)
267 * {
268 * std::cerr << "Exception: " << e.what() << "\n";
269 * }
270 * }
271 *
272 * // ...
273 *
274 * boost::asio::co_spawn(my_io_context,
275 * echo(std::move(my_tcp_socket)),
276 * boost::asio::detached);
277 * @endcode
278 */
279template <typename ExecutionContext, typename AwaitableExecutor,
280 BOOST_ASIO_COMPLETION_TOKEN_FOR(
281 void(std::exception_ptr)) CompletionToken
282 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
283 typename ExecutionContext::executor_type)>
284inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
285 CompletionToken, void(std::exception_ptr))
286co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a,
287 CompletionToken&& token
288 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
289 typename ExecutionContext::executor_type),
290 typename enable_if<
291 is_convertible<ExecutionContext&, execution_context&>::value
292 && is_convertible<typename ExecutionContext::executor_type,
293 AwaitableExecutor>::value
294 >::type* = 0);
295
296/// Spawn a new coroutined-based thread of execution.
297/**
298 * @param ex The executor that will be used to schedule the new thread of
299 * execution.
300 *
301 * @param f A nullary function object with a return type of the form
302 * @c boost::asio::awaitable<R,E> that will be used as the coroutine's entry
303 * point.
304 *
305 * @param token The completion token that will handle the notification that the
306 * thread of execution has completed. If @c R is @c void, the function
307 * signature of the completion handler must be:
308 *
309 * @code void handler(std::exception_ptr); @endcode
310 * Otherwise, the function signature of the completion handler must be:
311 * @code void handler(std::exception_ptr, R); @endcode
312 *
313 *
314 * @par Example
315 * @code
316 * boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
317 * {
318 * std::size_t bytes_transferred = 0;
319 *
320 * try
321 * {
322 * char data[1024];
323 * for (;;)
324 * {
325 * std::size_t n = co_await socket.async_read_some(
326 * boost::asio::buffer(data), boost::asio::use_awaitable);
327 *
328 * co_await boost::asio::async_write(socket,
329 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
330 *
331 * bytes_transferred += n;
332 * }
333 * }
334 * catch (const std::exception&)
335 * {
336 * }
337 *
338 * co_return bytes_transferred;
339 * }
340 *
341 * // ...
342 *
343 * boost::asio::co_spawn(my_executor,
344 * [socket = std::move(my_tcp_socket)]() mutable
345 * -> boost::asio::awaitable<void>
346 * {
347 * try
348 * {
349 * char data[1024];
350 * for (;;)
351 * {
352 * std::size_t n = co_await socket.async_read_some(
353 * boost::asio::buffer(data), boost::asio::use_awaitable);
354 *
355 * co_await boost::asio::async_write(socket,
356 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
357 * }
358 * }
359 * catch (const std::exception& e)
360 * {
361 * std::cerr << "Exception: " << e.what() << "\n";
362 * }
363 * }, boost::asio::detached);
364 * @endcode
92f5a8d4
TL
365 */
366template <typename Executor, typename F,
367 BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
368 typename result_of<F()>::type>::type) CompletionToken
369 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>
370BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
371 typename detail::awaitable_signature<typename result_of<F()>::type>::type)
372co_spawn(const Executor& ex, F&& f,
373 CompletionToken&& token
374 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor),
375 typename enable_if<
20effc67 376 is_executor<Executor>::value || execution::is_executor<Executor>::value
92f5a8d4
TL
377 >::type* = 0);
378
20effc67 379/// Spawn a new coroutined-based thread of execution.
92f5a8d4 380/**
20effc67
TL
381 * @param ctx An execution context that will provide the executor to be used to
382 * schedule the new thread of execution.
383 *
384 * @param f A nullary function object with a return type of the form
385 * @c boost::asio::awaitable<R,E> that will be used as the coroutine's entry
386 * point.
387 *
388 * @param token The completion token that will handle the notification that the
389 * thread of execution has completed. If @c R is @c void, the function
390 * signature of the completion handler must be:
391 *
392 * @code void handler(std::exception_ptr); @endcode
393 * Otherwise, the function signature of the completion handler must be:
394 * @code void handler(std::exception_ptr, R); @endcode
395 *
396 *
397 * @par Example
398 * @code
399 * boost::asio::awaitable<std::size_t> echo(tcp::socket socket)
400 * {
401 * std::size_t bytes_transferred = 0;
402 *
403 * try
404 * {
405 * char data[1024];
406 * for (;;)
407 * {
408 * std::size_t n = co_await socket.async_read_some(
409 * boost::asio::buffer(data), boost::asio::use_awaitable);
410 *
411 * co_await boost::asio::async_write(socket,
412 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
413 *
414 * bytes_transferred += n;
415 * }
416 * }
417 * catch (const std::exception&)
418 * {
419 * }
420 *
421 * co_return bytes_transferred;
422 * }
423 *
424 * // ...
92f5a8d4 425 *
20effc67
TL
426 * boost::asio::co_spawn(my_io_context,
427 * [socket = std::move(my_tcp_socket)]() mutable
428 * -> boost::asio::awaitable<void>
429 * {
430 * try
431 * {
432 * char data[1024];
433 * for (;;)
434 * {
435 * std::size_t n = co_await socket.async_read_some(
436 * boost::asio::buffer(data), boost::asio::use_awaitable);
92f5a8d4 437 *
20effc67
TL
438 * co_await boost::asio::async_write(socket,
439 * boost::asio::buffer(data, n), boost::asio::use_awaitable);
440 * }
441 * }
442 * catch (const std::exception& e)
443 * {
444 * std::cerr << "Exception: " << e.what() << "\n";
445 * }
446 * }, boost::asio::detached);
447 * @endcode
92f5a8d4
TL
448 */
449template <typename ExecutionContext, typename F,
450 BOOST_ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<
451 typename result_of<F()>::type>::type) CompletionToken
452 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(
453 typename ExecutionContext::executor_type)>
454BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
455 typename detail::awaitable_signature<typename result_of<F()>::type>::type)
456co_spawn(ExecutionContext& ctx, F&& f,
457 CompletionToken&& token
458 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(
459 typename ExecutionContext::executor_type),
460 typename enable_if<
461 is_convertible<ExecutionContext&, execution_context&>::value
462 >::type* = 0);
463
464} // namespace asio
465} // namespace boost
466
467#include <boost/asio/detail/pop_options.hpp>
468
469#include <boost/asio/impl/co_spawn.hpp>
470
471#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
472
473#endif // BOOST_ASIO_CO_SPAWN_HPP