diff options
Diffstat (limited to 'boost/asio/detail/impl/scheduler.ipp')
-rw-r--r-- | boost/asio/detail/impl/scheduler.ipp | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/boost/asio/detail/impl/scheduler.ipp b/boost/asio/detail/impl/scheduler.ipp index 9dae6836ce..4ef5c86688 100644 --- a/boost/asio/detail/impl/scheduler.ipp +++ b/boost/asio/detail/impl/scheduler.ipp @@ -2,7 +2,7 @@ // detail/impl/scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -23,6 +23,7 @@ #include <boost/asio/detail/reactor.hpp> #include <boost/asio/detail/scheduler.hpp> #include <boost/asio/detail/scheduler_thread_info.hpp> +#include <boost/asio/detail/signal_blocker.hpp> #include <boost/asio/detail/push_options.hpp> @@ -30,6 +31,24 @@ namespace boost { namespace asio { namespace detail { +class scheduler::thread_function +{ +public: + explicit thread_function(scheduler* s) + : this_(s) + { + } + + void operator()() + { + boost::system::error_code ec; + this_->run(ec); + } + +private: + scheduler* this_; +}; + struct scheduler::task_cleanup { ~task_cleanup() @@ -85,8 +104,8 @@ struct scheduler::work_cleanup thread_info* this_thread_; }; -scheduler::scheduler( - boost::asio::execution_context& ctx, int concurrency_hint) +scheduler::scheduler(boost::asio::execution_context& ctx, + int concurrency_hint, bool own_thread) : boost::asio::detail::execution_context_service_base<scheduler>(ctx), one_thread_(concurrency_hint == 1 || !BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING( @@ -100,17 +119,44 @@ scheduler::scheduler( outstanding_work_(0), stopped_(false), shutdown_(false), - concurrency_hint_(concurrency_hint) + concurrency_hint_(concurrency_hint), + thread_(0) { BOOST_ASIO_HANDLER_TRACKING_INIT; + + if (own_thread) + { + ++outstanding_work_; + boost::asio::detail::signal_blocker sb; + thread_ = new boost::asio::detail::thread(thread_function(this)); + } +} + +scheduler::~scheduler() +{ + if (thread_) + { + thread_->join(); + delete thread_; + } } void scheduler::shutdown() { mutex::scoped_lock lock(mutex_); shutdown_ = true; + if (thread_) + stop_all_threads(lock); lock.unlock(); + // Join thread to ensure task operation is returned to queue. + if (thread_) + { + thread_->join(); + delete thread_; + thread_ = 0; + } + // Destroy handler objects. while (!op_queue_.empty()) { |