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);
|
||||
|
||||
timer_queues_.get_all_timers(ops);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
timer_queues_.get_all_timers(ops);
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
}
|
||||
|
||||
io_service_.abandon_operations(ops);
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
{
|
||||
if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1)
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user