Disable GetQueuedCompletionStatus workaround on recent Windows versions.
This commit is contained in:
parent
9c1fd314c8
commit
eabbbace2d
@ -69,6 +69,7 @@ win_iocp_io_service::win_iocp_io_service(
|
||||
stopped_(0),
|
||||
stop_event_posted_(0),
|
||||
shutdown_(0),
|
||||
gqcs_timeout_(get_gqcs_timeout()),
|
||||
dispatch_required_(0)
|
||||
{
|
||||
ASIO_HANDLER_TRACKING_INIT;
|
||||
@ -116,7 +117,7 @@ void win_iocp_io_service::shutdown_service()
|
||||
dword_ptr_t completion_key = 0;
|
||||
LPOVERLAPPED overlapped = 0;
|
||||
::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
||||
&completion_key, &overlapped, gqcs_timeout);
|
||||
&completion_key, &overlapped, gqcs_timeout_);
|
||||
if (overlapped)
|
||||
{
|
||||
::InterlockedDecrement(&outstanding_work_);
|
||||
@ -362,7 +363,7 @@ size_t win_iocp_io_service::do_one(bool block, asio::error_code& ec)
|
||||
LPOVERLAPPED overlapped = 0;
|
||||
::SetLastError(0);
|
||||
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
|
||||
&completion_key, &overlapped, block ? gqcs_timeout : 0);
|
||||
&completion_key, &overlapped, block ? gqcs_timeout_ : 0);
|
||||
DWORD last_error = ::GetLastError();
|
||||
|
||||
if (overlapped)
|
||||
@ -453,6 +454,16 @@ size_t win_iocp_io_service::do_one(bool block, asio::error_code& ec)
|
||||
}
|
||||
}
|
||||
|
||||
DWORD win_iocp_io_service::get_gqcs_timeout()
|
||||
{
|
||||
OSVERSIONINFO version_info;
|
||||
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
if (::GetVersionEx(&version_info))
|
||||
if (version_info.dwMajorVersion >= 6)
|
||||
return INFINITE;
|
||||
return default_gqcs_timeout;
|
||||
}
|
||||
|
||||
void win_iocp_io_service::do_add_timer_queue(timer_queue_base& queue)
|
||||
{
|
||||
mutex::scoped_lock lock(dispatch_mutex_);
|
||||
|
@ -206,6 +206,9 @@ private:
|
||||
// either 0 or 1).
|
||||
ASIO_DECL size_t do_one(bool block, asio::error_code& ec);
|
||||
|
||||
// Helper to calculate the GetQueuedCompletionStatus timeout.
|
||||
ASIO_DECL static DWORD get_gqcs_timeout();
|
||||
|
||||
// Helper function to add a new timer queue.
|
||||
ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
|
||||
|
||||
@ -245,11 +248,11 @@ private:
|
||||
|
||||
enum
|
||||
{
|
||||
// Timeout to use with GetQueuedCompletionStatus. Some versions of windows
|
||||
// have a "bug" where a call to GetQueuedCompletionStatus can appear stuck
|
||||
// even though there are events waiting on the queue. Using a timeout helps
|
||||
// to work around the issue.
|
||||
gqcs_timeout = 500,
|
||||
// Timeout to use with GetQueuedCompletionStatus on older versions of
|
||||
// Windows. Some versions of windows have a "bug" where a call to
|
||||
// GetQueuedCompletionStatus can appear stuck even though there are events
|
||||
// waiting on the queue. Using a timeout helps to work around the issue.
|
||||
default_gqcs_timeout = 500,
|
||||
|
||||
// Maximum waitable timer timeout, in milliseconds.
|
||||
max_timeout_msec = 5 * 60 * 1000,
|
||||
@ -267,6 +270,9 @@ private:
|
||||
overlapped_contains_result = 2
|
||||
};
|
||||
|
||||
// Timeout to use with GetQueuedCompletionStatus.
|
||||
const DWORD gqcs_timeout_;
|
||||
|
||||
// Function object for processing timeouts in a background thread.
|
||||
struct timer_thread_function;
|
||||
friend struct timer_thread_function;
|
||||
|
Loading…
Reference in New Issue
Block a user