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