diff options
Diffstat (limited to 'boost/asio/detail/impl/win_iocp_io_context.ipp')
-rw-r--r-- | boost/asio/detail/impl/win_iocp_io_context.ipp | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/boost/asio/detail/impl/win_iocp_io_context.ipp b/boost/asio/detail/impl/win_iocp_io_context.ipp index 87637f0b5c..5bdc540972 100644 --- a/boost/asio/detail/impl/win_iocp_io_context.ipp +++ b/boost/asio/detail/impl/win_iocp_io_context.ipp @@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_context.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) @@ -24,6 +24,7 @@ #include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/handler_invoke_helpers.hpp> #include <boost/asio/detail/limits.hpp> +#include <boost/asio/detail/thread.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/win_iocp_io_context.hpp> @@ -33,6 +34,22 @@ namespace boost { namespace asio { namespace detail { +struct win_iocp_io_context::thread_function +{ + explicit thread_function(win_iocp_io_context* s) + : this_(s) + { + } + + void operator()() + { + boost::system::error_code ec; + this_->run(ec); + } + + win_iocp_io_context* this_; +}; + struct win_iocp_io_context::work_finished_on_block_exit { ~work_finished_on_block_exit() @@ -63,7 +80,7 @@ struct win_iocp_io_context::timer_thread_function }; win_iocp_io_context::win_iocp_io_context( - boost::asio::execution_context& ctx, int concurrency_hint) + boost::asio::execution_context& ctx, int concurrency_hint, bool own_thread) : execution_context_service_base<win_iocp_io_context>(ctx), iocp_(), outstanding_work_(0), @@ -85,6 +102,21 @@ win_iocp_io_context::win_iocp_io_context( boost::asio::error::get_system_category()); boost::asio::detail::throw_error(ec, "iocp"); } + + if (own_thread) + { + ::InterlockedIncrement(&outstanding_work_); + thread_.reset(new boost::asio::detail::thread(thread_function(this))); + } +} + +win_iocp_io_context::~win_iocp_io_context() +{ + if (thread_.get()) + { + thread_->join(); + thread_.reset(); + } } void win_iocp_io_context::shutdown() @@ -98,6 +130,13 @@ void win_iocp_io_context::shutdown() ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); } + if (thread_.get()) + { + thread_->join(); + thread_.reset(); + ::InterlockedDecrement(&outstanding_work_); + } + while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0) { op_queue<win_iocp_operation> ops; |