10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// detail/resolve_endpoint_op.hpp 30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying 80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP 120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP 130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp" 160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/error.hpp" 170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/io_service.hpp" 180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/ip/basic_resolver_iterator.hpp" 190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/addressof.hpp" 200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/bind_handler.hpp" 210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/fenced_block.hpp" 220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/handler_alloc_helpers.hpp" 230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/handler_invoke_helpers.hpp" 240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/operation.hpp" 250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/socket_ops.hpp" 260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp" 280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio { 300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail { 310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Protocol, typename Handler> 330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass resolve_endpoint_op : public operation 340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic: 360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_DEFINE_HANDLER_PTR(resolve_endpoint_op); 370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename Protocol::endpoint endpoint_type; 390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef asio::ip::basic_resolver_iterator<Protocol> iterator_type; 400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token, 420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const endpoint_type& endpoint, io_service_impl& ios, Handler& handler) 430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : operation(&resolve_endpoint_op::do_complete), 440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie cancel_token_(cancel_token), 450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_(endpoint), 460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie io_service_impl_(ios), 470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler_(ASIO_MOVE_CAST(Handler)(handler)) 480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static void do_complete(io_service_impl* owner, operation* base, 520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const asio::error_code& /*ec*/, 530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie std::size_t /*bytes_transferred*/) 540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Take ownership of the operation object. 560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base)); 570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ptr p = { asio::detail::addressof(o->handler_), o, o }; 580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (owner && owner != &o->io_service_impl_) 600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // The operation is being run on the worker io_service. Time to perform 620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // the resolver operation. 630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Perform the blocking endpoint resolution operation. 650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie char host_name[NI_MAXHOST]; 660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie char service_name[NI_MAXSERV]; 670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie socket_ops::background_getnameinfo(o->cancel_token_, o->endpoint_.data(), 680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie o->endpoint_.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV, 690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie o->endpoint_.protocol().type(), o->ec_); 700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie o->iter_ = iterator_type::create(o->endpoint_, host_name, service_name); 710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Pass operation back to main io_service for completion. 730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie o->io_service_impl_.post_deferred_completion(o); 740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie p.v = p.p = 0; 750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie else 770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // The operation has been returned to the main io_service. The completion 790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // handler is ready to be delivered. 800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_HANDLER_COMPLETION((o)); 820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Make a copy of the handler so that the memory can be deallocated 840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // before the upcall is made. Even if we're not about to make an upcall, 850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // a sub-object of the handler may be the true owner of the memory 860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // associated with the handler. Consequently, a local copy of the handler 870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // is required to ensure that any owning sub-object remains valid until 880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // after we have deallocated the memory here. 890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie detail::binder2<Handler, asio::error_code, iterator_type> 900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie handler(o->handler_, o->ec_, o->iter_); 910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie p.h = asio::detail::addressof(handler.handler_); 920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie p.reset(); 930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (owner) 950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie fenced_block b(fenced_block::half); 970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "...")); 980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio_handler_invoke_helpers::invoke(handler, handler.handler_); 990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_HANDLER_INVOCATION_END; 1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate: 1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie socket_ops::weak_cancel_token_type cancel_token_; 1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type endpoint_; 1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie io_service_impl& io_service_impl_; 1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie Handler handler_; 1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec_; 1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie iterator_type iter_; 1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail 1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio 1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp" 1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP 119