]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/impl/use_awaitable.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / impl / use_awaitable.hpp
CommitLineData
92f5a8d4
TL
1//
2// impl/use_awaitable.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~
4//
1e59de90 5// Copyright (c) 2003-2022 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_IMPL_USE_AWAITABLE_HPP
12#define BOOST_ASIO_IMPL_USE_AWAITABLE_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/asio/async_result.hpp>
1e59de90 20#include <boost/asio/cancellation_signal.hpp>
92f5a8d4
TL
21
22#include <boost/asio/detail/push_options.hpp>
23
24namespace boost {
25namespace asio {
26namespace detail {
27
28template <typename Executor, typename T>
29class awaitable_handler_base
30 : public awaitable_thread<Executor>
31{
32public:
33 typedef void result_type;
34 typedef awaitable<T, Executor> awaitable_type;
35
36 // Construct from the entry point of a new thread of execution.
1e59de90
TL
37 awaitable_handler_base(awaitable<awaitable_thread_entry_point, Executor> a,
38 const Executor& ex, cancellation_slot pcs, cancellation_state cs)
39 : awaitable_thread<Executor>(std::move(a), ex, pcs, cs)
92f5a8d4
TL
40 {
41 }
42
43 // Transfer ownership from another awaitable_thread.
44 explicit awaitable_handler_base(awaitable_thread<Executor>* h)
45 : awaitable_thread<Executor>(std::move(*h))
46 {
47 }
48
49protected:
50 awaitable_frame<T, Executor>* frame() noexcept
51 {
1e59de90
TL
52 return static_cast<awaitable_frame<T, Executor>*>(
53 this->entry_point()->top_of_stack_);
92f5a8d4
TL
54 }
55};
56
57template <typename, typename...>
58class awaitable_handler;
59
60template <typename Executor>
20effc67 61class awaitable_handler<Executor>
92f5a8d4
TL
62 : public awaitable_handler_base<Executor, void>
63{
64public:
65 using awaitable_handler_base<Executor, void>::awaitable_handler_base;
66
67 void operator()()
68 {
69 this->frame()->attach_thread(this);
70 this->frame()->return_void();
1e59de90 71 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
72 this->frame()->pop_frame();
73 this->pump();
74 }
75};
76
77template <typename Executor>
78class awaitable_handler<Executor, boost::system::error_code>
79 : public awaitable_handler_base<Executor, void>
80{
81public:
82 using awaitable_handler_base<Executor, void>::awaitable_handler_base;
83
84 void operator()(const boost::system::error_code& ec)
85 {
86 this->frame()->attach_thread(this);
87 if (ec)
88 this->frame()->set_error(ec);
89 else
90 this->frame()->return_void();
1e59de90 91 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
92 this->frame()->pop_frame();
93 this->pump();
94 }
95};
96
97template <typename Executor>
98class awaitable_handler<Executor, std::exception_ptr>
99 : public awaitable_handler_base<Executor, void>
100{
101public:
102 using awaitable_handler_base<Executor, void>::awaitable_handler_base;
103
104 void operator()(std::exception_ptr ex)
105 {
106 this->frame()->attach_thread(this);
107 if (ex)
108 this->frame()->set_except(ex);
109 else
110 this->frame()->return_void();
1e59de90 111 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
112 this->frame()->pop_frame();
113 this->pump();
114 }
115};
116
117template <typename Executor, typename T>
118class awaitable_handler<Executor, T>
119 : public awaitable_handler_base<Executor, T>
120{
121public:
122 using awaitable_handler_base<Executor, T>::awaitable_handler_base;
123
124 template <typename Arg>
125 void operator()(Arg&& arg)
126 {
127 this->frame()->attach_thread(this);
128 this->frame()->return_value(std::forward<Arg>(arg));
1e59de90 129 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
130 this->frame()->pop_frame();
131 this->pump();
132 }
133};
134
135template <typename Executor, typename T>
136class awaitable_handler<Executor, boost::system::error_code, T>
137 : public awaitable_handler_base<Executor, T>
138{
139public:
140 using awaitable_handler_base<Executor, T>::awaitable_handler_base;
141
142 template <typename Arg>
143 void operator()(const boost::system::error_code& ec, Arg&& arg)
144 {
145 this->frame()->attach_thread(this);
146 if (ec)
147 this->frame()->set_error(ec);
148 else
149 this->frame()->return_value(std::forward<Arg>(arg));
1e59de90 150 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
151 this->frame()->pop_frame();
152 this->pump();
153 }
154};
155
156template <typename Executor, typename T>
157class awaitable_handler<Executor, std::exception_ptr, T>
158 : public awaitable_handler_base<Executor, T>
159{
160public:
161 using awaitable_handler_base<Executor, T>::awaitable_handler_base;
162
163 template <typename Arg>
164 void operator()(std::exception_ptr ex, Arg&& arg)
165 {
166 this->frame()->attach_thread(this);
167 if (ex)
168 this->frame()->set_except(ex);
169 else
170 this->frame()->return_value(std::forward<Arg>(arg));
1e59de90 171 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
172 this->frame()->pop_frame();
173 this->pump();
174 }
175};
176
177template <typename Executor, typename... Ts>
178class awaitable_handler
179 : public awaitable_handler_base<Executor, std::tuple<Ts...>>
180{
181public:
182 using awaitable_handler_base<Executor,
183 std::tuple<Ts...>>::awaitable_handler_base;
184
185 template <typename... Args>
186 void operator()(Args&&... args)
187 {
188 this->frame()->attach_thread(this);
189 this->frame()->return_values(std::forward<Args>(args)...);
1e59de90 190 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
191 this->frame()->pop_frame();
192 this->pump();
193 }
194};
195
196template <typename Executor, typename... Ts>
197class awaitable_handler<Executor, boost::system::error_code, Ts...>
198 : public awaitable_handler_base<Executor, std::tuple<Ts...>>
199{
200public:
201 using awaitable_handler_base<Executor,
202 std::tuple<Ts...>>::awaitable_handler_base;
203
204 template <typename... Args>
205 void operator()(const boost::system::error_code& ec, Args&&... args)
206 {
207 this->frame()->attach_thread(this);
208 if (ec)
209 this->frame()->set_error(ec);
210 else
211 this->frame()->return_values(std::forward<Args>(args)...);
1e59de90 212 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
213 this->frame()->pop_frame();
214 this->pump();
215 }
216};
217
218template <typename Executor, typename... Ts>
219class awaitable_handler<Executor, std::exception_ptr, Ts...>
220 : public awaitable_handler_base<Executor, std::tuple<Ts...>>
221{
222public:
223 using awaitable_handler_base<Executor,
224 std::tuple<Ts...>>::awaitable_handler_base;
225
226 template <typename... Args>
227 void operator()(std::exception_ptr ex, Args&&... args)
228 {
229 this->frame()->attach_thread(this);
230 if (ex)
231 this->frame()->set_except(ex);
232 else
233 this->frame()->return_values(std::forward<Args>(args)...);
1e59de90 234 this->frame()->clear_cancellation_slot();
92f5a8d4
TL
235 this->frame()->pop_frame();
236 this->pump();
237 }
238};
239
240} // namespace detail
241
242#if !defined(GENERATING_DOCUMENTATION)
243
20effc67
TL
244#if defined(_MSC_VER)
245template <typename T>
246T dummy_return()
247{
248 return std::move(*static_cast<T*>(nullptr));
249}
250
251template <>
1e59de90 252inline void dummy_return()
20effc67
TL
253{
254}
255#endif // defined(_MSC_VER)
256
92f5a8d4
TL
257template <typename Executor, typename R, typename... Args>
258class async_result<use_awaitable_t<Executor>, R(Args...)>
259{
260public:
261 typedef typename detail::awaitable_handler<
262 Executor, typename decay<Args>::type...> handler_type;
263 typedef typename handler_type::awaitable_type return_type;
264
92f5a8d4 265 template <typename Initiation, typename... InitArgs>
1e59de90
TL
266#if defined(__APPLE_CC__) && (__clang_major__ == 13)
267 __attribute__((noinline))
268#endif // defined(__APPLE_CC__) && (__clang_major__ == 13)
269 static handler_type* do_init(
270 detail::awaitable_frame_base<Executor>* frame, Initiation& initiation,
271 use_awaitable_t<Executor> u, InitArgs&... args)
92f5a8d4 272 {
20effc67 273 (void)u;
1e59de90
TL
274 BOOST_ASIO_HANDLER_LOCATION((u.file_name_, u.line_, u.function_name_));
275 handler_type handler(frame->detach_thread());
276 std::move(initiation)(std::move(handler), std::move(args)...);
277 return nullptr;
278 }
20effc67 279
1e59de90
TL
280 template <typename Initiation, typename... InitArgs>
281 static return_type initiate(Initiation initiation,
282 use_awaitable_t<Executor> u, InitArgs... args)
283 {
284 co_await [&] (auto* frame)
92f5a8d4 285 {
1e59de90 286 return do_init(frame, initiation, u, args...);
92f5a8d4
TL
287 };
288
289 for (;;) {} // Never reached.
290#if defined(_MSC_VER)
291 co_return dummy_return<typename return_type::value_type>();
292#endif // defined(_MSC_VER)
293 }
294};
295
296#endif // !defined(GENERATING_DOCUMENTATION)
297
298} // namespace asio
299} // namespace boost
300
301#include <boost/asio/detail/pop_options.hpp>
302
303#endif // BOOST_ASIO_IMPL_USE_AWAITABLE_HPP