// 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
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
//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"
_GetEnvironmentStringsW,
_GetProcAddress,
_GetProcessAffinityMask,
- _GetQueuedCompletionStatus,
+ _GetQueuedCompletionStatusEx,
_GetStdHandle,
_GetSystemDirectoryA,
_GetSystemInfo,
// We will load syscalls, if available, before using them.
_AddDllDirectory,
_AddVectoredContinueHandler,
- _GetQueuedCompletionStatusEx,
_LoadLibraryExA,
_LoadLibraryExW,
_ stdFunction
}
_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)