Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:44

0001 //
0002 // detail/resolve_query_op.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_RESOLVE_QUERY_OP_HPP
0012 #define BOOST_ASIO_DETAIL_RESOLVE_QUERY_OP_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/bind_handler.hpp>
0020 #include <boost/asio/detail/fenced_block.hpp>
0021 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0022 #include <boost/asio/detail/handler_work.hpp>
0023 #include <boost/asio/detail/memory.hpp>
0024 #include <boost/asio/detail/resolve_op.hpp>
0025 #include <boost/asio/detail/socket_ops.hpp>
0026 #include <boost/asio/error.hpp>
0027 #include <boost/asio/ip/basic_resolver_query.hpp>
0028 #include <boost/asio/ip/basic_resolver_results.hpp>
0029 
0030 #if defined(BOOST_ASIO_HAS_IOCP)
0031 # include <boost/asio/detail/win_iocp_io_context.hpp>
0032 #else // defined(BOOST_ASIO_HAS_IOCP)
0033 # include <boost/asio/detail/scheduler.hpp>
0034 #endif // defined(BOOST_ASIO_HAS_IOCP)
0035 
0036 #include <boost/asio/detail/push_options.hpp>
0037 
0038 namespace boost {
0039 namespace asio {
0040 namespace detail {
0041 
0042 template <typename Protocol, typename Handler, typename IoExecutor>
0043 class resolve_query_op : public resolve_op
0044 {
0045 public:
0046   BOOST_ASIO_DEFINE_HANDLER_PTR(resolve_query_op);
0047 
0048   typedef boost::asio::ip::basic_resolver_query<Protocol> query_type;
0049   typedef boost::asio::ip::basic_resolver_results<Protocol> results_type;
0050 
0051 #if defined(BOOST_ASIO_HAS_IOCP)
0052   typedef class win_iocp_io_context scheduler_impl;
0053 #else
0054   typedef class scheduler scheduler_impl;
0055 #endif
0056 
0057   resolve_query_op(socket_ops::weak_cancel_token_type cancel_token,
0058       const query_type& qry, scheduler_impl& sched,
0059       Handler& handler, const IoExecutor& io_ex)
0060     : resolve_op(&resolve_query_op::do_complete),
0061       cancel_token_(cancel_token),
0062       query_(qry),
0063       scheduler_(sched),
0064       handler_(static_cast<Handler&&>(handler)),
0065       work_(handler_, io_ex),
0066       addrinfo_(0)
0067   {
0068   }
0069 
0070   ~resolve_query_op()
0071   {
0072     if (addrinfo_)
0073       socket_ops::freeaddrinfo(addrinfo_);
0074   }
0075 
0076   static void do_complete(void* owner, operation* base,
0077       const boost::system::error_code& /*ec*/,
0078       std::size_t /*bytes_transferred*/)
0079   {
0080     // Take ownership of the operation object.
0081     BOOST_ASIO_ASSUME(base != 0);
0082     resolve_query_op* o(static_cast<resolve_query_op*>(base));
0083     ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0084 
0085     if (owner && owner != &o->scheduler_)
0086     {
0087       // The operation is being run on the worker io_context. Time to perform
0088       // the resolver operation.
0089     
0090       // Perform the blocking host resolution operation.
0091       socket_ops::background_getaddrinfo(o->cancel_token_,
0092           o->query_.host_name().c_str(), o->query_.service_name().c_str(),
0093           o->query_.hints(), &o->addrinfo_, o->ec_);
0094 
0095       // Pass operation back to main io_context for completion.
0096       o->scheduler_.post_deferred_completion(o);
0097       p.v = p.p = 0;
0098     }
0099     else
0100     {
0101       // The operation has been returned to the main io_context. The completion
0102       // handler is ready to be delivered.
0103 
0104       BOOST_ASIO_HANDLER_COMPLETION((*o));
0105 
0106       // Take ownership of the operation's outstanding work.
0107       handler_work<Handler, IoExecutor> w(
0108           static_cast<handler_work<Handler, IoExecutor>&&>(
0109             o->work_));
0110 
0111       // Make a copy of the handler so that the memory can be deallocated
0112       // before the upcall is made. Even if we're not about to make an upcall,
0113       // a sub-object of the handler may be the true owner of the memory
0114       // associated with the handler. Consequently, a local copy of the handler
0115       // is required to ensure that any owning sub-object remains valid until
0116       // after we have deallocated the memory here.
0117       detail::binder2<Handler, boost::system::error_code, results_type>
0118         handler(o->handler_, o->ec_, results_type());
0119       p.h = boost::asio::detail::addressof(handler.handler_);
0120       if (o->addrinfo_)
0121       {
0122         handler.arg2_ = results_type::create(o->addrinfo_,
0123             o->query_.host_name(), o->query_.service_name());
0124       }
0125       p.reset();
0126 
0127       if (owner)
0128       {
0129         fenced_block b(fenced_block::half);
0130         BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "..."));
0131         w.complete(handler, handler.handler_);
0132         BOOST_ASIO_HANDLER_INVOCATION_END;
0133       }
0134     }
0135   }
0136 
0137 private:
0138   socket_ops::weak_cancel_token_type cancel_token_;
0139   query_type query_;
0140   scheduler_impl& scheduler_;
0141   Handler handler_;
0142   handler_work<Handler, IoExecutor> work_;
0143   boost::asio::detail::addrinfo_type* addrinfo_;
0144 };
0145 
0146 } // namespace detail
0147 } // namespace asio
0148 } // namespace boost
0149 
0150 #include <boost/asio/detail/pop_options.hpp>
0151 
0152 #endif // BOOST_ASIO_DETAIL_RESOLVE_QUERY_OP_HPP