1 //
2 // detail/resolver_service_base.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 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 BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP
12 #define BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/error.hpp>
20 #include <boost/asio/io_service.hpp>
21 #include <boost/asio/detail/mutex.hpp>
22 #include <boost/asio/detail/noncopyable.hpp>
23 #include <boost/asio/detail/operation.hpp>
24 #include <boost/asio/detail/socket_ops.hpp>
25 #include <boost/asio/detail/socket_types.hpp>
26 #include <boost/asio/detail/scoped_ptr.hpp>
27 #include <boost/asio/detail/thread.hpp>
28 
29 #include <boost/asio/detail/push_options.hpp>
30 
31 namespace boost {
32 namespace asio {
33 namespace detail {
34 
35 class resolver_service_base
36 {
37 public:
38   // The implementation type of the resolver. A cancellation token is used to
39   // indicate to the background thread that the operation has been cancelled.
40   typedef socket_ops::shared_cancel_token_type implementation_type;
41 
42   // Constructor.
43   BOOST_ASIO_DECL resolver_service_base(boost::asio::io_service& io_service);
44 
45   // Destructor.
46   BOOST_ASIO_DECL ~resolver_service_base();
47 
48   // Destroy all user-defined handler objects owned by the service.
49   BOOST_ASIO_DECL void shutdown_service();
50 
51   // Perform any fork-related housekeeping.
52   BOOST_ASIO_DECL void fork_service(
53       boost::asio::io_service::fork_event fork_ev);
54 
55   // Construct a new resolver implementation.
56   BOOST_ASIO_DECL void construct(implementation_type& impl);
57 
58   // Destroy a resolver implementation.
59   BOOST_ASIO_DECL void destroy(implementation_type&);
60 
61   // Cancel pending asynchronous operations.
62   BOOST_ASIO_DECL void cancel(implementation_type& impl);
63 
64 protected:
65   // Helper function to start an asynchronous resolve operation.
66   BOOST_ASIO_DECL void start_resolve_op(operation* op);
67 
68 #if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
69   // Helper class to perform exception-safe cleanup of addrinfo objects.
70   class auto_addrinfo
71     : private boost::asio::detail::noncopyable
72   {
73   public:
auto_addrinfo(boost::asio::detail::addrinfo_type * ai)74     explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai)
75       : ai_(ai)
76     {
77     }
78 
~auto_addrinfo()79     ~auto_addrinfo()
80     {
81       if (ai_)
82         socket_ops::freeaddrinfo(ai_);
83     }
84 
operator boost::asio::detail::addrinfo_type*()85     operator boost::asio::detail::addrinfo_type*()
86     {
87       return ai_;
88     }
89 
90   private:
91     boost::asio::detail::addrinfo_type* ai_;
92   };
93 #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
94 
95   // Helper class to run the work io_service in a thread.
96   class work_io_service_runner;
97 
98   // Start the work thread if it's not already running.
99   BOOST_ASIO_DECL void start_work_thread();
100 
101   // The io_service implementation used to post completions.
102   io_service_impl& io_service_impl_;
103 
104 private:
105   // Mutex to protect access to internal data.
106   boost::asio::detail::mutex mutex_;
107 
108   // Private io_service used for performing asynchronous host resolution.
109   boost::asio::detail::scoped_ptr<boost::asio::io_service> work_io_service_;
110 
111   // The work io_service implementation used to post completions.
112   io_service_impl& work_io_service_impl_;
113 
114   // Work for the private io_service to perform.
115   boost::asio::detail::scoped_ptr<boost::asio::io_service::work> work_;
116 
117   // Thread used for running the work io_service's run loop.
118   boost::asio::detail::scoped_ptr<boost::asio::detail::thread> work_thread_;
119 };
120 
121 } // namespace detail
122 } // namespace asio
123 } // namespace boost
124 
125 #include <boost/asio/detail/pop_options.hpp>
126 
127 #if defined(BOOST_ASIO_HEADER_ONLY)
128 # include <boost/asio/detail/impl/resolver_service_base.ipp>
129 #endif // defined(BOOST_ASIO_HEADER_ONLY)
130 
131 #endif // BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP
132