2 // detail/winrt_async_manager.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP
12 #define BOOST_ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
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/io_service.hpp>
28 #include <boost/asio/detail/push_options.hpp>
34 class winrt_async_manager
35 : public boost::asio::detail::service_base<winrt_async_manager>
39 winrt_async_manager(boost::asio::io_service& io_service)
40 : boost::asio::detail::service_base<winrt_async_manager>(io_service),
41 io_service_(use_service<io_service_impl>(io_service)),
47 ~winrt_async_manager()
51 // Destroy all user-defined handler objects owned by the service.
52 void shutdown_service()
54 if (--outstanding_ops_ > 0)
56 // Block until last operation is complete.
57 std::future<void> f = promise_.get_future();
62 void sync(Windows::Foundation::IAsyncAction^ action,
63 boost::system::error_code& ec)
65 using namespace Windows::Foundation;
66 using Windows::Foundation::AsyncStatus;
68 auto promise = std::make_shared<std::promise<boost::system::error_code>>();
69 auto future = promise->get_future();
71 action->Completed = ref new AsyncActionCompletedHandler(
72 [promise](IAsyncAction^ action, AsyncStatus status)
76 case AsyncStatus::Canceled:
77 promise->set_value(boost::asio::error::operation_aborted);
79 case AsyncStatus::Error:
80 case AsyncStatus::Completed:
82 boost::system::error_code ec(
83 action->ErrorCode.Value,
84 boost::system::system_category());
85 promise->set_value(ec);
93 template <typename TResult>
94 TResult sync(Windows::Foundation::IAsyncOperation<TResult>^ operation,
95 boost::system::error_code& ec)
97 using namespace Windows::Foundation;
98 using Windows::Foundation::AsyncStatus;
100 auto promise = std::make_shared<std::promise<boost::system::error_code>>();
101 auto future = promise->get_future();
103 operation->Completed = ref new AsyncOperationCompletedHandler<TResult>(
104 [promise](IAsyncOperation<TResult>^ operation, AsyncStatus status)
108 case AsyncStatus::Canceled:
109 promise->set_value(boost::asio::error::operation_aborted);
111 case AsyncStatus::Error:
112 case AsyncStatus::Completed:
114 boost::system::error_code ec(
115 operation->ErrorCode.Value,
116 boost::system::system_category());
117 promise->set_value(ec);
123 return operation->GetResults();
126 template <typename TResult, typename TProgress>
128 Windows::Foundation::IAsyncOperationWithProgress<
129 TResult, TProgress>^ operation,
130 boost::system::error_code& ec)
132 using namespace Windows::Foundation;
133 using Windows::Foundation::AsyncStatus;
135 auto promise = std::make_shared<std::promise<boost::system::error_code>>();
136 auto future = promise->get_future();
139 = ref new AsyncOperationWithProgressCompletedHandler<TResult, TProgress>(
140 [promise](IAsyncOperationWithProgress<TResult, TProgress>^ operation,
145 case AsyncStatus::Canceled:
146 promise->set_value(boost::asio::error::operation_aborted);
148 case AsyncStatus::Started:
150 case AsyncStatus::Error:
151 case AsyncStatus::Completed:
153 boost::system::error_code ec(
154 operation->ErrorCode.Value,
155 boost::system::system_category());
156 promise->set_value(ec);
162 return operation->GetResults();
165 void async(Windows::Foundation::IAsyncAction^ action,
166 winrt_async_op<void>* handler)
168 using namespace Windows::Foundation;
169 using Windows::Foundation::AsyncStatus;
171 auto on_completed = ref new AsyncActionCompletedHandler(
172 [this, handler](IAsyncAction^ action, AsyncStatus status)
176 case AsyncStatus::Canceled:
177 handler->ec_ = boost::asio::error::operation_aborted;
179 case AsyncStatus::Started:
181 case AsyncStatus::Completed:
182 case AsyncStatus::Error:
184 handler->ec_ = boost::system::error_code(
185 action->ErrorCode.Value,
186 boost::system::system_category());
189 io_service_.post_deferred_completion(handler);
190 if (--outstanding_ops_ == 0)
191 promise_.set_value();
194 io_service_.work_started();
196 action->Completed = on_completed;
199 template <typename TResult>
200 void async(Windows::Foundation::IAsyncOperation<TResult>^ operation,
201 winrt_async_op<TResult>* handler)
203 using namespace Windows::Foundation;
204 using Windows::Foundation::AsyncStatus;
206 auto on_completed = ref new AsyncOperationCompletedHandler<TResult>(
207 [this, handler](IAsyncOperation<TResult>^ operation, AsyncStatus status)
211 case AsyncStatus::Canceled:
212 handler->ec_ = boost::asio::error::operation_aborted;
214 case AsyncStatus::Started:
216 case AsyncStatus::Completed:
217 handler->result_ = operation->GetResults();
219 case AsyncStatus::Error:
221 handler->ec_ = boost::system::error_code(
222 operation->ErrorCode.Value,
223 boost::system::system_category());
226 io_service_.post_deferred_completion(handler);
227 if (--outstanding_ops_ == 0)
228 promise_.set_value();
231 io_service_.work_started();
233 operation->Completed = on_completed;
236 template <typename TResult, typename TProgress>
238 Windows::Foundation::IAsyncOperationWithProgress<
239 TResult, TProgress>^ operation,
240 winrt_async_op<TResult>* handler)
242 using namespace Windows::Foundation;
243 using Windows::Foundation::AsyncStatus;
246 = ref new AsyncOperationWithProgressCompletedHandler<TResult, TProgress>(
247 [this, handler](IAsyncOperationWithProgress<
248 TResult, TProgress>^ operation, AsyncStatus status)
252 case AsyncStatus::Canceled:
253 handler->ec_ = boost::asio::error::operation_aborted;
255 case AsyncStatus::Started:
257 case AsyncStatus::Completed:
258 handler->result_ = operation->GetResults();
260 case AsyncStatus::Error:
262 handler->ec_ = boost::system::error_code(
263 operation->ErrorCode.Value,
264 boost::system::system_category());
267 io_service_.post_deferred_completion(handler);
268 if (--outstanding_ops_ == 0)
269 promise_.set_value();
272 io_service_.work_started();
274 operation->Completed = on_completed;
278 // The io_service implementation used to post completed handlers.
279 io_service_impl& io_service_;
281 // Count of outstanding operations.
282 atomic_count outstanding_ops_;
284 // Used to keep wait for outstanding operations to complete.
285 std::promise<void> promise_;
288 } // namespace detail
292 #include <boost/asio/detail/pop_options.hpp>
294 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
296 #endif // BOOST_ASIO_DETAIL_WINRT_ASYNC_MANAGER_HPP