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).
This commit is contained in:
parent
d73439e218
commit
81a6a51c0c
@ -63,6 +63,8 @@ void dev_poll_reactor::shutdown_service()
|
|||||||
op_queue_[i].get_all_operations(ops);
|
op_queue_[i].get_all_operations(ops);
|
||||||
|
|
||||||
timer_queues_.get_all_timers(ops);
|
timer_queues_.get_all_timers(ops);
|
||||||
|
|
||||||
|
io_service_.abandon_operations(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper class to re-register all descriptors with /dev/poll.
|
// Helper class to re-register all descriptors with /dev/poll.
|
||||||
|
@ -84,6 +84,8 @@ void epoll_reactor::shutdown_service()
|
|||||||
}
|
}
|
||||||
|
|
||||||
timer_queues_.get_all_timers(ops);
|
timer_queues_.get_all_timers(ops);
|
||||||
|
|
||||||
|
io_service_.abandon_operations(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void epoll_reactor::fork_service(asio::io_service::fork_event fork_ev)
|
void epoll_reactor::fork_service(asio::io_service::fork_event fork_ev)
|
||||||
|
@ -74,6 +74,8 @@ void kqueue_reactor::shutdown_service()
|
|||||||
}
|
}
|
||||||
|
|
||||||
timer_queues_.get_all_timers(ops);
|
timer_queues_.get_all_timers(ops);
|
||||||
|
|
||||||
|
io_service_.abandon_operations(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kqueue_reactor::fork_service(asio::io_service::fork_event fork_ev)
|
void kqueue_reactor::fork_service(asio::io_service::fork_event fork_ev)
|
||||||
|
@ -81,6 +81,8 @@ void select_reactor::shutdown_service()
|
|||||||
op_queue_[i].get_all_operations(ops);
|
op_queue_[i].get_all_operations(ops);
|
||||||
|
|
||||||
timer_queues_.get_all_timers(ops);
|
timer_queues_.get_all_timers(ops);
|
||||||
|
|
||||||
|
io_service_.abandon_operations(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void select_reactor::fork_service(asio::io_service::fork_event fork_ev)
|
void select_reactor::fork_service(asio::io_service::fork_event fork_ev)
|
||||||
|
@ -145,6 +145,8 @@ void signal_set_service::shutdown_service()
|
|||||||
reg = reg->next_in_table_;
|
reg = reg->next_in_table_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
io_service_.abandon_operations(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void signal_set_service::fork_service(
|
void signal_set_service::fork_service(
|
||||||
|
@ -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,
|
std::size_t task_io_service::do_one(mutex::scoped_lock& lock,
|
||||||
task_io_service::idle_thread_info* this_idle_thread)
|
task_io_service::idle_thread_info* this_idle_thread)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
void win_iocp_io_service::on_pending(win_iocp_operation* op)
|
||||||
{
|
{
|
||||||
if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1)
|
if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1)
|
||||||
|
@ -105,6 +105,10 @@ public:
|
|||||||
// that work_started() was previously called for each operation.
|
// that work_started() was previously called for each operation.
|
||||||
ASIO_DECL void post_deferred_completions(op_queue<operation>& ops);
|
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:
|
private:
|
||||||
// Structure containing information about an idle thread.
|
// Structure containing information about an idle thread.
|
||||||
struct idle_thread_info;
|
struct idle_thread_info;
|
||||||
|
@ -126,6 +126,10 @@ public:
|
|||||||
ASIO_DECL void post_deferred_completions(
|
ASIO_DECL void post_deferred_completions(
|
||||||
op_queue<win_iocp_operation>& ops);
|
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
|
// Called after starting an overlapped I/O operation that did not complete
|
||||||
// immediately. The caller must have already called work_started() prior to
|
// immediately. The caller must have already called work_started() prior to
|
||||||
// starting the operation.
|
// starting the operation.
|
||||||
|
Loading…
Reference in New Issue
Block a user