• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//
2// detail/impl/resolver_service_base.ipp
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_IMPL_RESOLVER_SERVICE_BASE_IPP
12#define ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
13
14
15#include "asio/detail/config.hpp"
16#include "asio/detail/resolver_service_base.hpp"
17
18#include "asio/detail/push_options.hpp"
19
20namespace asio {
21namespace detail {
22
23class resolver_service_base::work_io_service_runner
24{
25public:
26  work_io_service_runner(asio::io_service& io_service)
27    : io_service_(io_service) {}
28  void operator()() { io_service_.run(); }
29private:
30  asio::io_service& io_service_;
31};
32
33resolver_service_base::resolver_service_base(
34    asio::io_service& io_service)
35  : io_service_impl_(asio::use_service<io_service_impl>(io_service)),
36    work_io_service_(new asio::io_service),
37    work_io_service_impl_(asio::use_service<
38        io_service_impl>(*work_io_service_)),
39    work_(new asio::io_service::work(*work_io_service_)),
40    work_thread_(0)
41{
42}
43
44resolver_service_base::~resolver_service_base()
45{
46  shutdown_service();
47}
48
49void resolver_service_base::shutdown_service()
50{
51  work_.reset();
52  if (work_io_service_.get())
53  {
54    work_io_service_->stop();
55    if (work_thread_.get())
56    {
57      work_thread_->join();
58      work_thread_.reset();
59    }
60    work_io_service_.reset();
61  }
62}
63
64void resolver_service_base::fork_service(
65    asio::io_service::fork_event fork_ev)
66{
67  if (work_thread_.get())
68  {
69    if (fork_ev == asio::io_service::fork_prepare)
70    {
71      work_io_service_->stop();
72      work_thread_->join();
73    }
74    else
75    {
76      work_io_service_->reset();
77      work_thread_.reset(new asio::detail::thread(
78            work_io_service_runner(*work_io_service_)));
79    }
80  }
81}
82
83void resolver_service_base::construct(
84    resolver_service_base::implementation_type& impl)
85{
86  impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
87}
88
89void resolver_service_base::destroy(
90    resolver_service_base::implementation_type& impl)
91{
92  ASIO_HANDLER_OPERATION(("resolver", &impl, "cancel"));
93
94  impl.reset();
95}
96
97void resolver_service_base::cancel(
98    resolver_service_base::implementation_type& impl)
99{
100  ASIO_HANDLER_OPERATION(("resolver", &impl, "cancel"));
101
102  impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
103}
104
105void resolver_service_base::start_resolve_op(operation* op)
106{
107  start_work_thread();
108  io_service_impl_.work_started();
109  work_io_service_impl_.post_immediate_completion(op, false);
110}
111
112void resolver_service_base::start_work_thread()
113{
114  asio::detail::mutex::scoped_lock lock(mutex_);
115  if (!work_thread_.get())
116  {
117    work_thread_.reset(new asio::detail::thread(
118          work_io_service_runner(*work_io_service_)));
119  }
120}
121
122} // namespace detail
123} // namespace asio
124
125#include "asio/detail/pop_options.hpp"
126
127#endif // ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
128