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