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:
Christopher Kohlhoff 2011-03-23 15:03:56 +11:00
parent d73439e218
commit 81a6a51c0c
9 changed files with 36 additions and 0 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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(

View File

@ -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)
{

View File

@ -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)

View File

@ -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;

View File

@ -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.