mirror of
https://github.com/golang/go
synced 2024-11-17 06:54:48 -07:00
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>
This commit is contained in:
parent
355f53f0a0
commit
e3cf0525b0
@ -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()
|
||||
}
|
||||
}
|
||||
errno = int32(getlasterror())
|
||||
if errno == _WAIT_TIMEOUT {
|
||||
return gList{}
|
||||
}
|
||||
} else {
|
||||
op = nil
|
||||
errno = 0
|
||||
qty = 0
|
||||
if delay != 0 {
|
||||
mp.blocked = true
|
||||
}
|
||||
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{}
|
||||
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())
|
||||
}
|
||||
if op == nil {
|
||||
println("runtime: GetQueuedCompletionStatus failed (errno=", errno, ")")
|
||||
throw("runtime: netpoll failed")
|
||||
}
|
||||
// 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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user