From e3cf0525b0ecfaeb9381108e8c7181cdc2abee57 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 23 Mar 2020 20:42:29 -0700 Subject: [PATCH] runtime: always use GetQueuedCompletionStatusEx on Windows We used to fall back to GetQueuedCompletionStatus if GetQueuedCompletionStatus was not available, but as of Go 1.11 we require Windows 7 or later, so GetQueuedCompletionStatusEx is always available. Fixes #37957 Change-Id: I7d8d49a92ab7b1f5afdc54a442f696aaf4a5168e Reviewed-on: https://go-review.googlesource.com/c/go/+/225059 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman --- src/runtime/netpoll_windows.go | 87 ++++++++++------------------------ src/runtime/os_windows.go | 6 +-- 2 files changed, 28 insertions(+), 65 deletions(-) diff --git a/src/runtime/netpoll_windows.go b/src/runtime/netpoll_windows.go index ced52cbd3a..28b2f6ef3b 100644 --- a/src/runtime/netpoll_windows.go +++ b/src/runtime/netpoll_windows.go @@ -75,7 +75,7 @@ func netpollBreak() { // delay > 0: block for up to that many nanoseconds func netpoll(delay int64) gList { var entries [64]overlappedEntry - var wait, qty, key, flags, n, i uint32 + var wait, qty, flags, n, i uint32 var errno int32 var op *net_op var toRun gList @@ -99,82 +99,47 @@ func netpoll(delay int64) gList { wait = 1e9 } - if _GetQueuedCompletionStatusEx != nil { - n = uint32(len(entries) / int(gomaxprocs)) - if n < 8 { - n = 8 - } - if delay != 0 { - mp.blocked = true - } - if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { - mp.blocked = false - errno = int32(getlasterror()) - if errno == _WAIT_TIMEOUT { - return gList{} - } - println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") - throw("runtime: netpoll failed") - } + n = uint32(len(entries) / int(gomaxprocs)) + if n < 8 { + n = 8 + } + if delay != 0 { + mp.blocked = true + } + if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { mp.blocked = false - for i = 0; i < n; i++ { - op = entries[i].op - if op != nil { - errno = 0 - qty = 0 - if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { - errno = int32(getlasterror()) - } - handlecompletion(&toRun, op, errno, qty) - } else { - if delay == 0 { - // Forward the notification to the - // blocked poller. - netpollBreak() - } - } - } - } else { - op = nil - errno = 0 - qty = 0 - if delay != 0 { - mp.blocked = true + errno = int32(getlasterror()) + if errno == _WAIT_TIMEOUT { + return gList{} } - if stdcall5(_GetQueuedCompletionStatus, iocphandle, uintptr(unsafe.Pointer(&qty)), uintptr(unsafe.Pointer(&key)), uintptr(unsafe.Pointer(&op)), uintptr(wait)) == 0 { - mp.blocked = false - errno = int32(getlasterror()) - if errno == _WAIT_TIMEOUT { - return gList{} - } - if op == nil { - println("runtime: GetQueuedCompletionStatus failed (errno=", errno, ")") - throw("runtime: netpoll failed") + println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") + throw("runtime: netpoll failed") + } + mp.blocked = false + for i = 0; i < n; i++ { + op = entries[i].op + if op != nil { + errno = 0 + qty = 0 + if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { + errno = int32(getlasterror()) } - // dequeued failed IO packet, so report that - } - mp.blocked = false - if op == nil { + handlecompletion(&toRun, op, errno, qty) + } else { if delay == 0 { // Forward the notification to the // blocked poller. netpollBreak() } - return gList{} } - handlecompletion(&toRun, op, errno, qty) } return toRun } func handlecompletion(toRun *gList, op *net_op, errno int32, qty uint32) { - if op == nil { - println("runtime: GetQueuedCompletionStatus returned op == nil") - throw("runtime: netpoll failed") - } mode := op.mode if mode != 'r' && mode != 'w' { - println("runtime: GetQueuedCompletionStatus returned invalid mode=", mode) + println("runtime: GetQueuedCompletionStatusEx returned invalid mode=", mode) throw("runtime: netpoll failed") } op.errno = errno diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index 26da169be8..1298a14017 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -28,7 +28,7 @@ const ( //go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW%0 "kernel32.dll" //go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress%2 "kernel32.dll" //go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll" -//go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus%5 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetQueuedCompletionStatusEx GetQueuedCompletionStatusEx%6 "kernel32.dll" //go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll" //go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll" //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" @@ -75,7 +75,7 @@ var ( _GetEnvironmentStringsW, _GetProcAddress, _GetProcessAffinityMask, - _GetQueuedCompletionStatus, + _GetQueuedCompletionStatusEx, _GetStdHandle, _GetSystemDirectoryA, _GetSystemInfo, @@ -111,7 +111,6 @@ var ( // We will load syscalls, if available, before using them. _AddDllDirectory, _AddVectoredContinueHandler, - _GetQueuedCompletionStatusEx, _LoadLibraryExA, _LoadLibraryExW, _ stdFunction @@ -239,7 +238,6 @@ func loadOptionalSyscalls() { } _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) - _GetQueuedCompletionStatusEx = windowsFindfunc(k32, []byte("GetQueuedCompletionStatusEx\000")) _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) -- 2.50.0