aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-03-23 20:42:29 -0700
committerIan Lance Taylor <iant@golang.org>2020-03-24 19:57:49 +0000
commite3cf0525b0ecfaeb9381108e8c7181cdc2abee57 (patch)
tree257db1f9140bfb4fb4843b29867a43c93537d399 /src
parent355f53f0a0a5d79032068d4914d7aea3435084ec (diff)
downloadgo-e3cf0525b0ecfaeb9381108e8c7181cdc2abee57.tar.xz
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 <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/netpoll_windows.go87
-rw-r--r--src/runtime/os_windows.go6
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)