1//
2// detail/resolve_endpoint_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 ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP
12#define ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP
13
14
15#include "asio/detail/config.hpp"
16#include "asio/error.hpp"
17#include "asio/io_service.hpp"
18#include "asio/ip/basic_resolver_iterator.hpp"
19#include "asio/detail/addressof.hpp"
20#include "asio/detail/bind_handler.hpp"
21#include "asio/detail/fenced_block.hpp"
22#include "asio/detail/handler_alloc_helpers.hpp"
23#include "asio/detail/handler_invoke_helpers.hpp"
24#include "asio/detail/operation.hpp"
25#include "asio/detail/socket_ops.hpp"
26
27#include "asio/detail/push_options.hpp"
28
29namespace asio {
30namespace detail {
31
32template <typename Protocol, typename Handler>
33class resolve_endpoint_op : public operation
34{
35public:
36  ASIO_DEFINE_HANDLER_PTR(resolve_endpoint_op);
37
38  typedef typename Protocol::endpoint endpoint_type;
39  typedef asio::ip::basic_resolver_iterator<Protocol> iterator_type;
40
41  resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token,
42      const endpoint_type& endpoint, io_service_impl& ios, Handler& handler)
43    : operation(&resolve_endpoint_op::do_complete),
44      cancel_token_(cancel_token),
45      endpoint_(endpoint),
46      io_service_impl_(ios),
47      handler_(ASIO_MOVE_CAST(Handler)(handler))
48  {
49  }
50
51  static void do_complete(io_service_impl* owner, operation* base,
52      const asio::error_code& /*ec*/,
53      std::size_t /*bytes_transferred*/)
54  {
55    // Take ownership of the operation object.
56    resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base));
57    ptr p = { asio::detail::addressof(o->handler_), o, o };
58
59    if (owner && owner != &o->io_service_impl_)
60    {
61      // The operation is being run on the worker io_service. Time to perform
62      // the resolver operation.
63
64      // Perform the blocking endpoint resolution operation.
65      char host_name[NI_MAXHOST];
66      char service_name[NI_MAXSERV];
67      socket_ops::background_getnameinfo(o->cancel_token_, o->endpoint_.data(),
68          o->endpoint_.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV,
69          o->endpoint_.protocol().type(), o->ec_);
70      o->iter_ = iterator_type::create(o->endpoint_, host_name, service_name);
71
72      // Pass operation back to main io_service for completion.
73      o->io_service_impl_.post_deferred_completion(o);
74      p.v = p.p = 0;
75    }
76    else
77    {
78      // The operation has been returned to the main io_service. The completion
79      // handler is ready to be delivered.
80
81      ASIO_HANDLER_COMPLETION((o));
82
83      // Make a copy of the handler so that the memory can be deallocated
84      // before the upcall is made. Even if we're not about to make an upcall,
85      // a sub-object of the handler may be the true owner of the memory
86      // associated with the handler. Consequently, a local copy of the handler
87      // is required to ensure that any owning sub-object remains valid until
88      // after we have deallocated the memory here.
89      detail::binder2<Handler, asio::error_code, iterator_type>
90        handler(o->handler_, o->ec_, o->iter_);
91      p.h = asio::detail::addressof(handler.handler_);
92      p.reset();
93
94      if (owner)
95      {
96        fenced_block b(fenced_block::half);
97        ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "..."));
98        asio_handler_invoke_helpers::invoke(handler, handler.handler_);
99        ASIO_HANDLER_INVOCATION_END;
100      }
101    }
102  }
103
104private:
105  socket_ops::weak_cancel_token_type cancel_token_;
106  endpoint_type endpoint_;
107  io_service_impl& io_service_impl_;
108  Handler handler_;
109  asio::error_code ec_;
110  iterator_type iter_;
111};
112
113} // namespace detail
114} // namespace asio
115
116#include "asio/detail/pop_options.hpp"
117
118#endif // ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP
119