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