summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp')
-rw-r--r--3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp399
1 files changed, 38 insertions, 361 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp b/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp
index f9b7a98..1b734a0 100644
--- a/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp
+++ b/3rdParty/Boost/src/boost/asio/detail/resolver_service.hpp
@@ -1,6 +1,6 @@
//
-// resolver_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/resolver_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
@@ -15,69 +15,26 @@
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <cstring>
-#include <boost/scoped_ptr.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/config.hpp>
#include <boost/asio/ip/basic_resolver_iterator.hpp>
#include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/fenced_block.hpp>
-#include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/operation.hpp>
-#include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/thread.hpp>
+#include <boost/asio/detail/resolve_endpoint_op.hpp>
+#include <boost/asio/detail/resolve_op.hpp>
+#include <boost/asio/detail/resolver_service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
template <typename Protocol>
-class resolver_service
- : public boost::asio::detail::service_base<resolver_service<Protocol> >
+class resolver_service : public resolver_service_base
{
-private:
- // Helper class to perform exception-safe cleanup of addrinfo objects.
- class auto_addrinfo
- : private boost::asio::detail::noncopyable
- {
- public:
- explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai)
- : ai_(ai)
- {
- }
-
- ~auto_addrinfo()
- {
- if (ai_)
- socket_ops::freeaddrinfo(ai_);
- }
-
- operator boost::asio::detail::addrinfo_type*()
- {
- return ai_;
- }
-
- private:
- boost::asio::detail::addrinfo_type* ai_;
- };
-
public:
- // The implementation type of the resolver. The shared pointer is used as a
- // cancellation token to indicate to the background thread that the operation
- // has been cancelled.
- typedef boost::shared_ptr<void> implementation_type;
- struct noop_deleter { void operator()(void*) {} };
+ // The implementation type of the resolver. A cancellation token is used to
+ // indicate to the background thread that the operation has been cancelled.
+ typedef socket_ops::shared_cancel_token_type implementation_type;
// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
@@ -90,55 +47,8 @@ public:
// Constructor.
resolver_service(boost::asio::io_service& io_service)
- : boost::asio::detail::service_base<
- resolver_service<Protocol> >(io_service),
- mutex_(),
- io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)),
- work_io_service_(new boost::asio::io_service),
- work_io_service_impl_(boost::asio::use_service<
- io_service_impl>(*work_io_service_)),
- work_(new boost::asio::io_service::work(*work_io_service_)),
- work_thread_(0)
- {
- }
-
- // Destructor.
- ~resolver_service()
+ : resolver_service_base(io_service)
{
- shutdown_service();
- }
-
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- work_.reset();
- if (work_io_service_)
- {
- work_io_service_->stop();
- if (work_thread_)
- {
- work_thread_->join();
- work_thread_.reset();
- }
- work_io_service_.reset();
- }
- }
-
- // Construct a new resolver implementation.
- void construct(implementation_type& impl)
- {
- impl.reset(static_cast<void*>(0), noop_deleter());
- }
-
- // Destroy a resolver implementation.
- void destroy(implementation_type&)
- {
- }
-
- // Cancel pending asynchronous operations.
- void cancel(implementation_type& impl)
- {
- impl.reset(static_cast<void*>(0), noop_deleter());
}
// Resolve a query to a list of entries.
@@ -146,293 +56,60 @@ public:
boost::system::error_code& ec)
{
boost::asio::detail::addrinfo_type* address_info = 0;
- std::string host_name = query.host_name();
- std::string service_name = query.service_name();
- boost::asio::detail::addrinfo_type hints = query.hints();
- socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0,
- service_name.c_str(), &hints, &address_info, ec);
+ socket_ops::getaddrinfo(query.host_name().c_str(),
+ query.service_name().c_str(), query.hints(), &address_info, ec);
auto_addrinfo auto_address_info(address_info);
- if (ec)
- return iterator_type();
-
- return iterator_type::create(address_info, host_name, service_name);
+ return ec ? iterator_type() : iterator_type::create(
+ address_info, query.host_name(), query.service_name());
}
- template <typename Handler>
- class resolve_op
- : public operation
- {
- public:
- resolve_op(implementation_type impl, const query_type& query,
- io_service_impl& io_service_impl, Handler handler)
- : operation(&resolve_op::do_complete),
- impl_(impl),
- query_(query),
- io_service_impl_(io_service_impl),
- handler_(handler)
- {
- }
-
- static void do_complete(io_service_impl* owner, operation* base,
- boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
- {
- // Take ownership of the operation object.
- resolve_op* o(static_cast<resolve_op*>(base));
- typedef handler_alloc_traits<Handler, resolve_op> alloc_traits;
- handler_ptr<alloc_traits> ptr(o->handler_, o);
-
- if (owner)
- {
- if (owner != &o->io_service_impl_)
- {
- // The operation is being run on the worker io_service. Time to
- // perform the resolver operation.
-
- if (o->impl_.expired())
- {
- // THe operation has been cancelled.
- o->ec_ = boost::asio::error::operation_aborted;
- }
- else
- {
- // Perform the blocking host resolution operation.
- boost::asio::detail::addrinfo_type* address_info = 0;
- std::string host_name = o->query_.host_name();
- std::string service_name = o->query_.service_name();
- boost::asio::detail::addrinfo_type hints = o->query_.hints();
- socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0,
- service_name.c_str(), &hints, &address_info, o->ec_);
- auto_addrinfo auto_address_info(address_info);
- o->iter_ = iterator_type::create(
- address_info, host_name, service_name);
- }
-
- o->io_service_impl_.post_deferred_completion(o);
- ptr.release();
- }
- else
- {
- // The operation has been returned to the main io_serice. The
- // completion handler is ready to be delivered.
-
- // Make a copy of the handler so that the memory can be deallocated
- // before the upcall is made. Even if we're not about to make an
- // upcall, a sub-object of the handler may be the true owner of the
- // memory associated with the handler. Consequently, a local copy of
- // the handler is required to ensure that any owning sub-object
- // remains valid until after we have deallocated the memory here.
- detail::binder2<Handler, boost::system::error_code, iterator_type>
- handler(o->handler_, o->ec_, o->iter_);
- ptr.reset();
- boost::asio::detail::fenced_block b;
- boost_asio_handler_invoke_helpers::invoke(handler, handler);
- }
- }
- }
-
- private:
- boost::weak_ptr<void> impl_;
- query_type query_;
- io_service_impl& io_service_impl_;
- Handler handler_;
- boost::system::error_code ec_;
- iterator_type iter_;
- };
-
// Asynchronously resolve a query to a list of entries.
template <typename Handler>
void async_resolve(implementation_type& impl, const query_type& query,
Handler handler)
{
// Allocate and construct an operation to wrap the handler.
- typedef resolve_op<Handler> value_type;
- typedef handler_alloc_traits<Handler, value_type> alloc_traits;
- raw_handler_ptr<alloc_traits> raw_ptr(handler);
- handler_ptr<alloc_traits> ptr(raw_ptr,
- impl, query, io_service_impl_, handler);
-
- if (work_io_service_)
- {
- start_work_thread();
- io_service_impl_.work_started();
- work_io_service_impl_.post_immediate_completion(ptr.get());
- ptr.release();
- }
+ typedef resolve_op<Protocol, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl, query, io_service_impl_, handler);
+
+ start_resolve_op(p.p);
+ p.v = p.p = 0;
}
// Resolve an endpoint to a list of entries.
iterator_type resolve(implementation_type&,
const endpoint_type& endpoint, boost::system::error_code& ec)
{
- // First try resolving with the service name. If that fails try resolving
- // but allow the service to be returned as a number.
char host_name[NI_MAXHOST];
char service_name[NI_MAXSERV];
- int flags = endpoint.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
- socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
- host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
- if (ec)
- {
- flags |= NI_NUMERICSERV;
- socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
- host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
- }
+ socket_ops::sync_getnameinfo(endpoint.data(), endpoint.size(),
+ host_name, NI_MAXHOST, service_name, NI_MAXSERV,
+ endpoint.protocol().type(), ec);
- if (ec)
- return iterator_type();
-
- return iterator_type::create(endpoint, host_name, service_name);
+ return ec ? iterator_type() : iterator_type::create(
+ endpoint, host_name, service_name);
}
- template <typename Handler>
- class resolve_endpoint_op
- : public operation
- {
- public:
- resolve_endpoint_op(implementation_type impl, const endpoint_type& ep,
- io_service_impl& io_service_impl, Handler handler)
- : operation(&resolve_endpoint_op::do_complete),
- impl_(impl),
- ep_(ep),
- io_service_impl_(io_service_impl),
- handler_(handler)
- {
- }
-
- static void do_complete(io_service_impl* owner, operation* base,
- boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
- {
- // Take ownership of the operation object.
- resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base));
- typedef handler_alloc_traits<Handler, resolve_endpoint_op> alloc_traits;
- handler_ptr<alloc_traits> ptr(o->handler_, o);
-
- if (owner)
- {
- if (owner != &o->io_service_impl_)
- {
- // The operation is being run on the worker io_service. Time to
- // perform the resolver operation.
-
- if (o->impl_.expired())
- {
- // THe operation has been cancelled.
- o->ec_ = boost::asio::error::operation_aborted;
- }
- else
- {
- // Perform the blocking endoint resolution operation.
- char host_name[NI_MAXHOST];
- char service_name[NI_MAXSERV];
- int flags = o->ep_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
- socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(),
- host_name, NI_MAXHOST, service_name,
- NI_MAXSERV, flags, o->ec_);
- if (o->ec_)
- {
- flags |= NI_NUMERICSERV;
- socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(),
- host_name, NI_MAXHOST, service_name,
- NI_MAXSERV, flags, o->ec_);
- }
- o->iter_ = iterator_type::create(o->ep_, host_name, service_name);
- }
-
- o->io_service_impl_.post_deferred_completion(o);
- ptr.release();
- }
- else
- {
- // The operation has been returned to the main io_serice. The
- // completion handler is ready to be delivered.
-
- // Make a copy of the handler so that the memory can be deallocated
- // before the upcall is made. Even if we're not about to make an
- // upcall, a sub-object of the handler may be the true owner of the
- // memory associated with the handler. Consequently, a local copy of
- // the handler is required to ensure that any owning sub-object
- // remains valid until after we have deallocated the memory here.
- detail::binder2<Handler, boost::system::error_code, iterator_type>
- handler(o->handler_, o->ec_, o->iter_);
- ptr.reset();
- boost::asio::detail::fenced_block b;
- boost_asio_handler_invoke_helpers::invoke(handler, handler);
- }
- }
- }
-
- private:
- boost::weak_ptr<void> impl_;
- endpoint_type ep_;
- io_service_impl& io_service_impl_;
- Handler handler_;
- boost::system::error_code ec_;
- iterator_type iter_;
- };
-
// Asynchronously resolve an endpoint to a list of entries.
template <typename Handler>
void async_resolve(implementation_type& impl, const endpoint_type& endpoint,
Handler handler)
{
// Allocate and construct an operation to wrap the handler.
- typedef resolve_endpoint_op<Handler> value_type;
- typedef handler_alloc_traits<Handler, value_type> alloc_traits;
- raw_handler_ptr<alloc_traits> raw_ptr(handler);
- handler_ptr<alloc_traits> ptr(raw_ptr,
- impl, endpoint, io_service_impl_, handler);
-
- if (work_io_service_)
- {
- start_work_thread();
- io_service_impl_.work_started();
- work_io_service_impl_.post_immediate_completion(ptr.get());
- ptr.release();
- }
- }
-
-private:
- // Helper class to run the work io_service in a thread.
- class work_io_service_runner
- {
- public:
- work_io_service_runner(boost::asio::io_service& io_service)
- : io_service_(io_service) {}
- void operator()() { io_service_.run(); }
- private:
- boost::asio::io_service& io_service_;
- };
-
- // Start the work thread if it's not already running.
- void start_work_thread()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (!work_thread_)
- {
- work_thread_.reset(new boost::asio::detail::thread(
- work_io_service_runner(*work_io_service_)));
- }
+ typedef resolve_endpoint_op<Protocol, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl, endpoint, io_service_impl_, handler);
+
+ start_resolve_op(p.p);
+ p.v = p.p = 0;
}
-
- // Mutex to protect access to internal data.
- boost::asio::detail::mutex mutex_;
-
- // The io_service implementation used to post completions.
- io_service_impl& io_service_impl_;
-
- // Private io_service used for performing asynchronous host resolution.
- boost::scoped_ptr<boost::asio::io_service> work_io_service_;
-
- // The work io_service implementation used to post completions.
- io_service_impl& work_io_service_impl_;
-
- // Work for the private io_service to perform.
- boost::scoped_ptr<boost::asio::io_service::work> work_;
-
- // Thread used for running the work io_service's run loop.
- boost::scoped_ptr<boost::asio::detail::thread> work_thread_;
};
} // namespace detail