summaryrefslogtreecommitdiff
path: root/boost/asio/detail/impl/win_iocp_io_context.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/asio/detail/impl/win_iocp_io_context.ipp')
-rw-r--r--boost/asio/detail/impl/win_iocp_io_context.ipp43
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;