1 // 2 // detail/winrt_resolve_op.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 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_RESOLVE_OP_HPP 12 #define BOOST_ASIO_DETAIL_WINRT_RESOLVE_OP_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 <boost/asio/detail/addressof.hpp> 23 #include <boost/asio/detail/bind_handler.hpp> 24 #include <boost/asio/detail/fenced_block.hpp> 25 #include <boost/asio/detail/handler_alloc_helpers.hpp> 26 #include <boost/asio/detail/handler_invoke_helpers.hpp> 27 #include <boost/asio/detail/winrt_async_op.hpp> 28 #include <boost/asio/ip/basic_resolver_iterator.hpp> 29 #include <boost/asio/error.hpp> 30 31 #include <boost/asio/detail/push_options.hpp> 32 33 namespace boost { 34 namespace asio { 35 namespace detail { 36 37 template <typename Protocol, typename Handler> 38 class winrt_resolve_op : 39 public winrt_async_op< 40 Windows::Foundation::Collections::IVectorView< 41 Windows::Networking::EndpointPair^>^> 42 { 43 public: 44 BOOST_ASIO_DEFINE_HANDLER_PTR(winrt_resolve_op); 45 46 typedef typename Protocol::endpoint endpoint_type; 47 typedef boost::asio::ip::basic_resolver_query<Protocol> query_type; 48 typedef boost::asio::ip::basic_resolver_iterator<Protocol> iterator_type; 49 winrt_resolve_op(const query_type & query,Handler & handler)50 winrt_resolve_op(const query_type& query, Handler& handler) 51 : winrt_async_op< 52 Windows::Foundation::Collections::IVectorView< 53 Windows::Networking::EndpointPair^>^>( 54 &winrt_resolve_op::do_complete), 55 query_(query), 56 handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) 57 { 58 } 59 do_complete(io_service_impl * owner,operation * base,const boost::system::error_code &,std::size_t)60 static void do_complete(io_service_impl* owner, operation* base, 61 const boost::system::error_code&, std::size_t) 62 { 63 // Take ownership of the operation object. 64 winrt_resolve_op* o(static_cast<winrt_resolve_op*>(base)); 65 ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; 66 67 BOOST_ASIO_HANDLER_COMPLETION((o)); 68 69 iterator_type iterator = iterator_type(); 70 if (!o->ec_) 71 { 72 try 73 { 74 iterator = iterator_type::create( 75 o->result_, o->query_.hints(), 76 o->query_.host_name(), o->query_.service_name()); 77 } 78 catch (Platform::Exception^ e) 79 { 80 o->ec_ = boost::system::error_code(e->HResult, 81 boost::system::system_category()); 82 } 83 } 84 85 // Make a copy of the handler so that the memory can be deallocated before 86 // the upcall is made. Even if we're not about to make an upcall, a 87 // sub-object of the handler may be the true owner of the memory associated 88 // with the handler. Consequently, a local copy of the handler is required 89 // to ensure that any owning sub-object remains valid until after we have 90 // deallocated the memory here. 91 detail::binder2<Handler, boost::system::error_code, iterator_type> 92 handler(o->handler_, o->ec_, iterator); 93 p.h = boost::asio::detail::addressof(handler.handler_); 94 p.reset(); 95 96 // Make the upcall if required. 97 if (owner) 98 { 99 fenced_block b(fenced_block::half); 100 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_)); 101 boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); 102 BOOST_ASIO_HANDLER_INVOCATION_END; 103 } 104 } 105 106 private: 107 query_type query_; 108 Handler handler_; 109 }; 110 111 } // namespace detail 112 } // namespace asio 113 } // namespace boost 114 115 #include <boost/asio/detail/pop_options.hpp> 116 117 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) 118 119 #endif // BOOST_ASIO_DETAIL_WINRT_RESOLVE_OP_HPP 120