]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/detail/winrt_async_manager.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / detail / winrt_async_manager.hpp
1 //
2 // detail/winrt_async_manager.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 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_DETAIL_WINRT_ASYNC_MANAGER_HPP
12 #define BOOST_ASIO_DETAIL_WINRT_ASYNC_MANAGER_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_WINDOWS_RUNTIME)
21
22 #include <future>
23 #include <boost/asio/detail/atomic_count.hpp>
24 #include <boost/asio/detail/winrt_async_op.hpp>
25 #include <boost/asio/error.hpp>
26 #include <boost/asio/execution_context.hpp>
27
28 #if defined(BOOST_ASIO_HAS_IOCP)
29 # include <boost/asio/detail/win_iocp_io_context.hpp>
30 #else // defined(BOOST_ASIO_HAS_IOCP)
31 # include <boost/asio/detail/scheduler.hpp>
32 #endif // defined(BOOST_ASIO_HAS_IOCP)
33
34 #include <boost/asio/detail/push_options.hpp>
35
36 namespace boost {
37 namespace asio {
38 namespace detail {
39
40 class winrt_async_manager
41 : public execution_context_service_base<winrt_async_manager>
42 {
43 public:
44 // Constructor.
45 winrt_async_manager(execution_context& context)
46 : execution_context_service_base<winrt_async_manager>(context),
47 scheduler_(use_service<scheduler_impl>(context)),
48 outstanding_ops_(1)
49 {
50 }
51
52 // Destructor.
53 ~winrt_async_manager()
54 {
55 }
56
57 // Destroy all user-defined handler objects owned by the service.
58 void shutdown()
59 {
60 if (--outstanding_ops_ > 0)
61 {
62 // Block until last operation is complete.
63 std::future<void> f = promise_.get_future();
64 f.wait();
65 }
66 }
67
68 void sync(Windows::Foundation::IAsyncAction^ action,
69 boost::system::error_code& ec)
70 {
71 using namespace Windows::Foundation;
72 using Windows::Foundation::AsyncStatus;
73
74 auto promise = std::make_shared<std::promise<boost::system::error_code>>();
75 auto future = promise->get_future();
76
77 action->Completed = ref new AsyncActionCompletedHandler(
78 [promise](IAsyncAction^ action, AsyncStatus status)
79 {
80 switch (status)
81 {
82 case AsyncStatus::Canceled:
83 promise->set_value(boost::asio::error::operation_aborted);
84 break;
85 case AsyncStatus::Error:
86 case AsyncStatus::Completed:
87 default:
88 boost::system::error_code ec(
89 action->ErrorCode.Value,
90 boost::system::system_category());
91 promise->set_value(ec);
92 break;
93 }
94 });
95
96 ec = future.get();
97 }
98
99 template <typename TResult>
100 TResult sync(Windows::Foundation::IAsyncOperation<TResult>^ operation,
101 boost::system::error_code& ec)
102 {
103 using namespace Windows::Foundation;
104 using Windows::Foundation::AsyncStatus;
105
106 auto promise = std::make_shared<std::promise<boost::system::error_code>>();
107 auto future = promise->get_future();
108
109 operation->Completed = ref new AsyncOperationCompletedHandler<TResult>(
110 [promise](IAsyncOperation<TResult>^ operation, AsyncStatus status)
111 {
112 switch (status)
113 {
114 case AsyncStatus::Canceled:
115 promise->set_value(boost::asio::error::operation_aborted);
116 break;
117 case AsyncStatus::Error:
118 case AsyncStatus::Completed:
119 default:
120 boost::system::error_code ec(
121 operation->ErrorCode.Value,
122 boost::system::system_category());
123 promise->set_value(ec);
124 break;
125 }
126 });
127
128 ec = future.get();
129 return operation->GetResults();
130 }
131
132 template <typename TResult, typename TProgress>
133 TResult sync(
134 Windows::Foundation::IAsyncOperationWithProgress<
135 TResult, TProgress>^ operation,
136 boost::system::error_code& ec)
137 {
138 using namespace Windows::Foundation;
139 using Windows::Foundation::AsyncStatus;
140
141 auto promise = std::make_shared<std::promise<boost::system::error_code>>();
142 auto future = promise->get_future();
143
144 operation->Completed
145 = ref new AsyncOperationWithProgressCompletedHandler<TResult, TProgress>(
146 [promise](IAsyncOperationWithProgress<TResult, TProgress>^ operation,
147 AsyncStatus status)
148 {
149 switch (status)
150 {
151 case AsyncStatus::Canceled:
152 promise->set_value(boost::asio::error::operation_aborted);
153 break;
154 case AsyncStatus::Started:
155 break;
156 case AsyncStatus::Error:
157 case AsyncStatus::Completed:
158 default:
159 boost::system::error_code ec(
160 operation->ErrorCode.Value,
161 boost::system::system_category());
162 promise->set_value(ec);
163 break;
164 }
165 });
166
167 ec = future.get();
168 return operation->GetResults();
169 }
170
171 void async(Windows::Foundation::IAsyncAction^ action,
172 winrt_async_op<void>* handler)
173 {
174 using namespace Windows::Foundation;
175 using Windows::Foundation::AsyncStatus;
176
177 auto on_completed = ref new AsyncActionCompletedHandler(
178 [this, handler](IAsyncAction^ action, AsyncStatus status)
179 {
180 switch (status)
181 {
182 case AsyncStatus::Canceled:
183 handler->ec_ = boost::asio::error::operation_aborted;
184 break;
185 case AsyncStatus::Started:
186 return;
187 case AsyncStatus::Completed:
188 case AsyncStatus::Error:
189 default:
190 handler->ec_ = boost::system::error_code(
191 action->ErrorCode.Value,
192 boost::system::system_category());
193 break;
194 }
195 scheduler_.post_deferred_completion(handler);
196 if (--outstanding_ops_ == 0)
197 promise_.set_value();
198 });
199
200 scheduler_.work_started();
201 ++outstanding_ops_;
202 action->Completed = on_completed;
203 }
204
205 template <typename TResult>
206 void async(Windows::Foundation::IAsyncOperation<TResult>^ operation,
207 winrt_async_op<TResult>* handler)
208 {
209 using namespace Windows::Foundation;
210 using Windows::Foundation::AsyncStatus;
211
212 auto on_completed = ref new AsyncOperationCompletedHandler<TResult>(
213 [this, handler](IAsyncOperation<TResult>^ operation, AsyncStatus status)
214 {
215 switch (status)
216 {
217 case AsyncStatus::Canceled:
218 handler->ec_ = boost::asio::error::operation_aborted;
219 break;
220 case AsyncStatus::Started:
221 return;
222 case AsyncStatus::Completed:
223 handler->result_ = operation->GetResults();
224 // Fall through.
225 case AsyncStatus::Error:
226 default:
227 handler->ec_ = boost::system::error_code(
228 operation->ErrorCode.Value,
229 boost::system::system_category());
230 break;
231 }
232 scheduler_.post_deferred_completion(handler);
233 if (--outstanding_ops_ == 0)
234 promise_.set_value();
235 });
236
237 scheduler_.work_started();
238 ++outstanding_ops_;
239 operation->Completed = on_completed;
240 }
241
242 template <typename TResult, typename TProgress>
243 void async(
244 Windows::Foundation::IAsyncOperationWithProgress<
245 TResult, TProgress>^ operation,
246 winrt_async_op<TResult>* handler)
247 {
248 using namespace Windows::Foundation;
249 using Windows::Foundation::AsyncStatus;
250
251 auto on_completed
252 = ref new AsyncOperationWithProgressCompletedHandler<TResult, TProgress>(
253 [this, handler](IAsyncOperationWithProgress<
254 TResult, TProgress>^ operation, AsyncStatus status)
255 {
256 switch (status)
257 {
258 case AsyncStatus::Canceled:
259 handler->ec_ = boost::asio::error::operation_aborted;
260 break;
261 case AsyncStatus::Started:
262 return;
263 case AsyncStatus::Completed:
264 handler->result_ = operation->GetResults();
265 // Fall through.
266 case AsyncStatus::Error:
267 default:
268 handler->ec_ = boost::system::error_code(
269 operation->ErrorCode.Value,
270 boost::system::system_category());
271 break;
272 }
273 scheduler_.post_deferred_completion(handler);
274 if (--outstanding_ops_ == 0)
275 promise_.set_value();
276 });
277
278 scheduler_.work_started();
279 ++outstanding_ops_;
280 operation->Completed = on_completed;
281 }
282
283 private:
284 // The scheduler implementation used to post completed handlers.
285 #if defined(BOOST_ASIO_HAS_IOCP)
286 typedef class win_iocp_io_context scheduler_impl;
287 #else
288 typedef class scheduler scheduler_impl;
289 #endif
290 scheduler_impl& scheduler_;
291
292 // Count of outstanding operations.
293 atomic_count outstanding_ops_;
294
295 // Used to keep wait for outstanding operations to complete.
296 std::promise<void> promise_;
297 };
298
299 } // namespace detail
300 } // namespace asio
301 } // namespace boost
302
303 #include <boost/asio/detail/pop_options.hpp>
304
305 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
306
307 #endif // BOOST_ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP