File indexing completed on 2025-01-18 09:28:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
0012 #define BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/resolver_service_base.hpp>
0020
0021 #include <boost/asio/detail/push_options.hpp>
0022
0023 namespace boost {
0024 namespace asio {
0025 namespace detail {
0026
0027 class resolver_service_base::work_scheduler_runner
0028 {
0029 public:
0030 work_scheduler_runner(scheduler_impl& work_scheduler)
0031 : work_scheduler_(work_scheduler)
0032 {
0033 }
0034
0035 void operator()()
0036 {
0037 boost::system::error_code ec;
0038 work_scheduler_.run(ec);
0039 }
0040
0041 private:
0042 scheduler_impl& work_scheduler_;
0043 };
0044
0045 resolver_service_base::resolver_service_base(execution_context& context)
0046 : scheduler_(boost::asio::use_service<scheduler_impl>(context)),
0047 work_scheduler_(new scheduler_impl(context, -1, false)),
0048 work_thread_(0)
0049 {
0050 work_scheduler_->work_started();
0051 }
0052
0053 resolver_service_base::~resolver_service_base()
0054 {
0055 base_shutdown();
0056 }
0057
0058 void resolver_service_base::base_shutdown()
0059 {
0060 if (work_scheduler_.get())
0061 {
0062 work_scheduler_->work_finished();
0063 work_scheduler_->stop();
0064 if (work_thread_.get())
0065 {
0066 work_thread_->join();
0067 work_thread_.reset();
0068 }
0069 work_scheduler_.reset();
0070 }
0071 }
0072
0073 void resolver_service_base::base_notify_fork(
0074 execution_context::fork_event fork_ev)
0075 {
0076 if (work_thread_.get())
0077 {
0078 if (fork_ev == execution_context::fork_prepare)
0079 {
0080 work_scheduler_->stop();
0081 work_thread_->join();
0082 work_thread_.reset();
0083 }
0084 }
0085 else if (fork_ev != execution_context::fork_prepare)
0086 {
0087 work_scheduler_->restart();
0088 }
0089 }
0090
0091 void resolver_service_base::construct(
0092 resolver_service_base::implementation_type& impl)
0093 {
0094 impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
0095 }
0096
0097 void resolver_service_base::destroy(
0098 resolver_service_base::implementation_type& impl)
0099 {
0100 BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
0101 "resolver", &impl, 0, "cancel"));
0102
0103 impl.reset();
0104 }
0105
0106 void resolver_service_base::move_construct(implementation_type& impl,
0107 implementation_type& other_impl)
0108 {
0109 impl = static_cast<implementation_type&&>(other_impl);
0110 }
0111
0112 void resolver_service_base::move_assign(implementation_type& impl,
0113 resolver_service_base&, implementation_type& other_impl)
0114 {
0115 destroy(impl);
0116 impl = static_cast<implementation_type&&>(other_impl);
0117 }
0118
0119 void resolver_service_base::cancel(
0120 resolver_service_base::implementation_type& impl)
0121 {
0122 BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
0123 "resolver", &impl, 0, "cancel"));
0124
0125 impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
0126 }
0127
0128 void resolver_service_base::start_resolve_op(resolve_op* op)
0129 {
0130 if (BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
0131 scheduler_.concurrency_hint()))
0132 {
0133 start_work_thread();
0134 scheduler_.work_started();
0135 work_scheduler_->post_immediate_completion(op, false);
0136 }
0137 else
0138 {
0139 op->ec_ = boost::asio::error::operation_not_supported;
0140 scheduler_.post_immediate_completion(op, false);
0141 }
0142 }
0143
0144 void resolver_service_base::start_work_thread()
0145 {
0146 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0147 if (!work_thread_.get())
0148 {
0149 work_thread_.reset(new boost::asio::detail::thread(
0150 work_scheduler_runner(*work_scheduler_)));
0151 }
0152 }
0153
0154 }
0155 }
0156 }
0157
0158 #include <boost/asio/detail/pop_options.hpp>
0159
0160 #endif