File indexing completed on 2026-08-17 08:37:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP
0012 #define BOOST_ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_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/memory.hpp>
0021 #include <boost/asio/detail/resolver_thread_pool.hpp>
0022 #include <boost/asio/error.hpp>
0023
0024 #include <boost/asio/detail/push_options.hpp>
0025
0026 namespace boost {
0027 namespace asio {
0028 namespace detail {
0029
0030 class resolver_thread_pool::work_scheduler_runner
0031 {
0032 public:
0033 work_scheduler_runner(scheduler_impl& work_scheduler)
0034 : work_scheduler_(work_scheduler)
0035 {
0036 }
0037
0038 void operator()()
0039 {
0040 boost::system::error_code ec;
0041 work_scheduler_.run(ec);
0042 }
0043
0044 private:
0045 scheduler_impl& work_scheduler_;
0046 };
0047
0048 resolver_thread_pool::resolver_thread_pool(execution_context& context)
0049 : execution_context_service_base<resolver_thread_pool>(context),
0050 scheduler_(boost::asio::use_service<scheduler_impl>(context)),
0051 work_scheduler_(scheduler_impl::internal(), context),
0052 work_threads_(execution_context::allocator<void>(context)),
0053 num_work_threads_(config(context).get("resolver", "threads", 0U)),
0054 scheduler_locking_(config(context).get("scheduler", "locking", true)),
0055 shutdown_(false)
0056 {
0057 work_scheduler_.work_started();
0058 if (num_work_threads_ > 0)
0059 start_work_threads();
0060 else
0061 num_work_threads_ = 1;
0062 }
0063
0064 resolver_thread_pool::~resolver_thread_pool()
0065 {
0066 shutdown();
0067 }
0068
0069 void resolver_thread_pool::shutdown()
0070 {
0071 if (!shutdown_)
0072 {
0073 work_scheduler_.work_finished();
0074 work_scheduler_.stop();
0075 work_threads_.join();
0076 work_scheduler_.shutdown();
0077 shutdown_ = true;
0078 }
0079 }
0080
0081 void resolver_thread_pool::notify_fork(execution_context::fork_event fork_ev)
0082 {
0083 if (!work_threads_.empty())
0084 {
0085 if (fork_ev == execution_context::fork_prepare)
0086 {
0087 work_scheduler_.stop();
0088 work_threads_.join();
0089 }
0090 }
0091 else if (fork_ev != execution_context::fork_prepare)
0092 {
0093 work_scheduler_.restart();
0094 }
0095 }
0096
0097 void resolver_thread_pool::start_resolve_op(resolve_op* op)
0098 {
0099 if (scheduler_locking_)
0100 {
0101 start_work_threads();
0102 scheduler_.work_started();
0103 work_scheduler_.post_immediate_completion(op, false);
0104 }
0105 else
0106 {
0107 op->ec_ = boost::asio::error::operation_not_supported;
0108 scheduler_.post_immediate_completion(op, false);
0109 }
0110 }
0111
0112 void resolver_thread_pool::start_work_threads()
0113 {
0114 boost::asio::detail::mutex::scoped_lock lock(mutex_);
0115 if (work_threads_.empty())
0116 for (unsigned int i = 0; i < num_work_threads_; ++i)
0117 work_threads_.create_thread(work_scheduler_runner(work_scheduler_));
0118 }
0119
0120 }
0121 }
0122 }
0123
0124 #include <boost/asio/detail/pop_options.hpp>
0125
0126 #endif