Created
June 29, 2013 07:11
-
-
Save Jackarain/5890195 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 81a6a51c0cb66de6bc77e1fa5dcd46b2794995e4 Mon Sep 17 00:00:00 2001 | |
From: Christopher Kohlhoff <[email protected]> | |
Date: Wed, 23 Mar 2011 15:03:56 +1100 | |
Subject: [PATCH] On Windows, ensure the count of outstanding work is decremented for | |
abandoned operations (i.e. operations that are being cleaned up within | |
the io_service destructor). | |
--- | |
asio/include/asio/detail/impl/dev_poll_reactor.ipp | 2 ++ | |
asio/include/asio/detail/impl/epoll_reactor.ipp | 2 ++ | |
asio/include/asio/detail/impl/kqueue_reactor.ipp | 2 ++ | |
asio/include/asio/detail/impl/select_reactor.ipp | 2 ++ | |
.../asio/detail/impl/signal_set_service.ipp | 2 ++ | |
asio/include/asio/detail/impl/task_io_service.ipp | 7 +++++++ | |
.../asio/detail/impl/win_iocp_io_service.ipp | 11 +++++++++++ | |
asio/include/asio/detail/task_io_service.hpp | 4 ++++ | |
asio/include/asio/detail/win_iocp_io_service.hpp | 4 ++++ | |
9 files changed, 36 insertions(+), 0 deletions(-) | |
diff --git a/asio/include/asio/detail/impl/dev_poll_reactor.ipp b/asio/include/asio/detail/impl/dev_poll_reactor.ipp | |
index 06d89ea..2a01993 100644 | |
--- a/asio/include/asio/detail/impl/dev_poll_reactor.ipp | |
+++ b/asio/include/asio/detail/impl/dev_poll_reactor.ipp | |
@@ -63,6 +63,8 @@ void dev_poll_reactor::shutdown_service() | |
op_queue_[i].get_all_operations(ops); | |
timer_queues_.get_all_timers(ops); | |
+ | |
+ io_service_.abandon_operations(ops); | |
} | |
// Helper class to re-register all descriptors with /dev/poll. | |
diff --git a/asio/include/asio/detail/impl/epoll_reactor.ipp b/asio/include/asio/detail/impl/epoll_reactor.ipp | |
index 22f567a..d08dedb 100644 | |
--- a/asio/include/asio/detail/impl/epoll_reactor.ipp | |
+++ b/asio/include/asio/detail/impl/epoll_reactor.ipp | |
@@ -84,6 +84,8 @@ void epoll_reactor::shutdown_service() | |
} | |
timer_queues_.get_all_timers(ops); | |
+ | |
+ io_service_.abandon_operations(ops); | |
} | |
void epoll_reactor::fork_service(asio::io_service::fork_event fork_ev) | |
diff --git a/asio/include/asio/detail/impl/kqueue_reactor.ipp b/asio/include/asio/detail/impl/kqueue_reactor.ipp | |
index f0cdf73..45aff60 100644 | |
--- a/asio/include/asio/detail/impl/kqueue_reactor.ipp | |
+++ b/asio/include/asio/detail/impl/kqueue_reactor.ipp | |
@@ -74,6 +74,8 @@ void kqueue_reactor::shutdown_service() | |
} | |
timer_queues_.get_all_timers(ops); | |
+ | |
+ io_service_.abandon_operations(ops); | |
} | |
void kqueue_reactor::fork_service(asio::io_service::fork_event fork_ev) | |
diff --git a/asio/include/asio/detail/impl/select_reactor.ipp b/asio/include/asio/detail/impl/select_reactor.ipp | |
index f4e0314..00fd9fc 100644 | |
--- a/asio/include/asio/detail/impl/select_reactor.ipp | |
+++ b/asio/include/asio/detail/impl/select_reactor.ipp | |
@@ -81,6 +81,8 @@ void select_reactor::shutdown_service() | |
op_queue_[i].get_all_operations(ops); | |
timer_queues_.get_all_timers(ops); | |
+ | |
+ io_service_.abandon_operations(ops); | |
} | |
void select_reactor::fork_service(asio::io_service::fork_event fork_ev) | |
diff --git a/asio/include/asio/detail/impl/signal_set_service.ipp b/asio/include/asio/detail/impl/signal_set_service.ipp | |
index f0f0e78..4cde184 100644 | |
--- a/asio/include/asio/detail/impl/signal_set_service.ipp | |
+++ b/asio/include/asio/detail/impl/signal_set_service.ipp | |
@@ -145,6 +145,8 @@ void signal_set_service::shutdown_service() | |
reg = reg->next_in_table_; | |
} | |
} | |
+ | |
+ io_service_.abandon_operations(ops); | |
} | |
void signal_set_service::fork_service( | |
diff --git a/asio/include/asio/detail/impl/task_io_service.ipp b/asio/include/asio/detail/impl/task_io_service.ipp | |
index cb585d5..0a2c6fa 100644 | |
--- a/asio/include/asio/detail/impl/task_io_service.ipp | |
+++ b/asio/include/asio/detail/impl/task_io_service.ipp | |
@@ -230,6 +230,13 @@ void task_io_service::post_deferred_completions( | |
} | |
} | |
+void task_io_service::abandon_operations( | |
+ op_queue<task_io_service::operation>& ops) | |
+{ | |
+ op_queue<task_io_service::operation> ops2; | |
+ ops2.push(ops); | |
+} | |
+ | |
std::size_t task_io_service::do_one(mutex::scoped_lock& lock, | |
task_io_service::idle_thread_info* this_idle_thread) | |
{ | |
diff --git a/asio/include/asio/detail/impl/win_iocp_io_service.ipp b/asio/include/asio/detail/impl/win_iocp_io_service.ipp | |
index ca3125e..7aaa6b8 100644 | |
--- a/asio/include/asio/detail/impl/win_iocp_io_service.ipp | |
+++ b/asio/include/asio/detail/impl/win_iocp_io_service.ipp | |
@@ -262,6 +262,17 @@ void win_iocp_io_service::post_deferred_completions( | |
} | |
} | |
+void win_iocp_io_service::abandon_operations( | |
+ op_queue<win_iocp_operation>& ops) | |
+{ | |
+ while (win_iocp_operation* op = ops.front()) | |
+ { | |
+ ops.pop(); | |
+ ::InterlockedDecrement(&outstanding_work_); | |
+ op->destroy(); | |
+ } | |
+} | |
+ | |
void win_iocp_io_service::on_pending(win_iocp_operation* op) | |
{ | |
if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1) | |
diff --git a/asio/include/asio/detail/task_io_service.hpp b/asio/include/asio/detail/task_io_service.hpp | |
index 285d83e..654f83c 100644 | |
--- a/asio/include/asio/detail/task_io_service.hpp | |
+++ b/asio/include/asio/detail/task_io_service.hpp | |
@@ -105,6 +105,10 @@ public: | |
// that work_started() was previously called for each operation. | |
ASIO_DECL void post_deferred_completions(op_queue<operation>& ops); | |
+ // Process unfinished operations as part of a shutdown_service operation. | |
+ // Assumes that work_started() was previously called for the operations. | |
+ ASIO_DECL void abandon_operations(op_queue<operation>& ops); | |
+ | |
private: | |
// Structure containing information about an idle thread. | |
struct idle_thread_info; | |
diff --git a/asio/include/asio/detail/win_iocp_io_service.hpp b/asio/include/asio/detail/win_iocp_io_service.hpp | |
index a562834..b5d7f0b 100644 | |
--- a/asio/include/asio/detail/win_iocp_io_service.hpp | |
+++ b/asio/include/asio/detail/win_iocp_io_service.hpp | |
@@ -126,6 +126,10 @@ public: | |
ASIO_DECL void post_deferred_completions( | |
op_queue<win_iocp_operation>& ops); | |
+ // Enqueue unfinished operation as part of a shutdown_service operation. | |
+ // Assumes that work_started() was previously called for the operations. | |
+ ASIO_DECL void abandon_operations(op_queue<operation>& ops); | |
+ | |
// Called after starting an overlapped I/O operation that did not complete | |
// immediately. The caller must have already called work_started() prior to | |
// starting the operation. | |
-- | |
1.7.0.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment