Chris@16
|
1 //
|
Chris@16
|
2 // detail/impl/resolver_service_base.ipp
|
Chris@16
|
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
Chris@16
|
4 //
|
Chris@101
|
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
Chris@16
|
6 //
|
Chris@16
|
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
|
Chris@16
|
12 #define BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
|
Chris@16
|
13
|
Chris@16
|
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
15 # pragma once
|
Chris@16
|
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/asio/detail/config.hpp>
|
Chris@16
|
19 #include <boost/asio/detail/resolver_service_base.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 #include <boost/asio/detail/push_options.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost {
|
Chris@16
|
24 namespace asio {
|
Chris@16
|
25 namespace detail {
|
Chris@16
|
26
|
Chris@16
|
27 class resolver_service_base::work_io_service_runner
|
Chris@16
|
28 {
|
Chris@16
|
29 public:
|
Chris@16
|
30 work_io_service_runner(boost::asio::io_service& io_service)
|
Chris@16
|
31 : io_service_(io_service) {}
|
Chris@16
|
32 void operator()() { io_service_.run(); }
|
Chris@16
|
33 private:
|
Chris@16
|
34 boost::asio::io_service& io_service_;
|
Chris@16
|
35 };
|
Chris@16
|
36
|
Chris@16
|
37 resolver_service_base::resolver_service_base(
|
Chris@16
|
38 boost::asio::io_service& io_service)
|
Chris@16
|
39 : io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)),
|
Chris@16
|
40 work_io_service_(new boost::asio::io_service),
|
Chris@16
|
41 work_io_service_impl_(boost::asio::use_service<
|
Chris@16
|
42 io_service_impl>(*work_io_service_)),
|
Chris@16
|
43 work_(new boost::asio::io_service::work(*work_io_service_)),
|
Chris@16
|
44 work_thread_(0)
|
Chris@16
|
45 {
|
Chris@16
|
46 }
|
Chris@16
|
47
|
Chris@16
|
48 resolver_service_base::~resolver_service_base()
|
Chris@16
|
49 {
|
Chris@16
|
50 shutdown_service();
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 void resolver_service_base::shutdown_service()
|
Chris@16
|
54 {
|
Chris@16
|
55 work_.reset();
|
Chris@16
|
56 if (work_io_service_.get())
|
Chris@16
|
57 {
|
Chris@16
|
58 work_io_service_->stop();
|
Chris@16
|
59 if (work_thread_.get())
|
Chris@16
|
60 {
|
Chris@16
|
61 work_thread_->join();
|
Chris@16
|
62 work_thread_.reset();
|
Chris@16
|
63 }
|
Chris@16
|
64 work_io_service_.reset();
|
Chris@16
|
65 }
|
Chris@16
|
66 }
|
Chris@16
|
67
|
Chris@16
|
68 void resolver_service_base::fork_service(
|
Chris@16
|
69 boost::asio::io_service::fork_event fork_ev)
|
Chris@16
|
70 {
|
Chris@16
|
71 if (work_thread_.get())
|
Chris@16
|
72 {
|
Chris@16
|
73 if (fork_ev == boost::asio::io_service::fork_prepare)
|
Chris@16
|
74 {
|
Chris@16
|
75 work_io_service_->stop();
|
Chris@16
|
76 work_thread_->join();
|
Chris@16
|
77 }
|
Chris@16
|
78 else
|
Chris@16
|
79 {
|
Chris@16
|
80 work_io_service_->reset();
|
Chris@16
|
81 work_thread_.reset(new boost::asio::detail::thread(
|
Chris@16
|
82 work_io_service_runner(*work_io_service_)));
|
Chris@16
|
83 }
|
Chris@16
|
84 }
|
Chris@16
|
85 }
|
Chris@16
|
86
|
Chris@16
|
87 void resolver_service_base::construct(
|
Chris@16
|
88 resolver_service_base::implementation_type& impl)
|
Chris@16
|
89 {
|
Chris@16
|
90 impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
|
Chris@16
|
91 }
|
Chris@16
|
92
|
Chris@16
|
93 void resolver_service_base::destroy(
|
Chris@16
|
94 resolver_service_base::implementation_type& impl)
|
Chris@16
|
95 {
|
Chris@16
|
96 BOOST_ASIO_HANDLER_OPERATION(("resolver", &impl, "cancel"));
|
Chris@16
|
97
|
Chris@16
|
98 impl.reset();
|
Chris@16
|
99 }
|
Chris@16
|
100
|
Chris@16
|
101 void resolver_service_base::cancel(
|
Chris@16
|
102 resolver_service_base::implementation_type& impl)
|
Chris@16
|
103 {
|
Chris@16
|
104 BOOST_ASIO_HANDLER_OPERATION(("resolver", &impl, "cancel"));
|
Chris@16
|
105
|
Chris@16
|
106 impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 void resolver_service_base::start_resolve_op(operation* op)
|
Chris@16
|
110 {
|
Chris@16
|
111 start_work_thread();
|
Chris@16
|
112 io_service_impl_.work_started();
|
Chris@16
|
113 work_io_service_impl_.post_immediate_completion(op, false);
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 void resolver_service_base::start_work_thread()
|
Chris@16
|
117 {
|
Chris@16
|
118 boost::asio::detail::mutex::scoped_lock lock(mutex_);
|
Chris@16
|
119 if (!work_thread_.get())
|
Chris@16
|
120 {
|
Chris@16
|
121 work_thread_.reset(new boost::asio::detail::thread(
|
Chris@16
|
122 work_io_service_runner(*work_io_service_)));
|
Chris@16
|
123 }
|
Chris@16
|
124 }
|
Chris@16
|
125
|
Chris@16
|
126 } // namespace detail
|
Chris@16
|
127 } // namespace asio
|
Chris@16
|
128 } // namespace boost
|
Chris@16
|
129
|
Chris@16
|
130 #include <boost/asio/detail/pop_options.hpp>
|
Chris@16
|
131
|
Chris@16
|
132 #endif // BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
|