// fields used by runtime.netpoll
runtimeCtx uintptr
mode int32
- errno int32
- qty uint32
// fields used only by net package
fd *FD
rsan int32
handle syscall.Handle
flags uint32
+ qty uint32
bufs []syscall.WSABuf
}
// Wait for our request to complete.
err = fd.pd.wait(int(o.mode), fd.isFile)
if err == nil {
+ err = windows.WSAGetOverlappedResult(fd.Sysfd, &o.o, &o.qty, false, &o.flags)
// All is good. Extract our IO results and return.
- if o.errno != 0 {
- err = syscall.Errno(o.errno)
+ if err != nil {
// More data available. Return back the size of received data.
if err == syscall.ERROR_MORE_DATA || err == windows.WSAEMSGSIZE {
return int(o.qty), err
}
// Wait for cancellation to complete.
fd.pd.waitCanceled(int(o.mode))
- if o.errno != 0 {
- err = syscall.Errno(o.errno)
+ err = windows.WSAGetOverlappedResult(fd.Sysfd, &o.o, &o.qty, false, &o.flags)
+ if err != nil {
if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
err = netpollErr
}
}
//sys WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW
+//sys WSAGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
func loadWSASendRecvMsg() error {
sendRecvMsgFunc.once.Do(func() {
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
procGetProfilesDirectoryW = moduserenv.NewProc("GetProfilesDirectoryW")
+ procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
procWSASocketW = modws2_32.NewProc("WSASocketW")
)
return
}
+func WSAGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
+ var _p0 uint32
+ if wait {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags))
handle = syscall.Handle(r0)
// used by windows
o overlapped
// used by netpoll
- pd *pollDesc
- mode int32
- errno int32
- qty uint32
+ pd *pollDesc
+ mode int32
}
type overlappedEntry struct {
// delay > 0: block for up to that many nanoseconds
func netpoll(delay int64) (gList, int32) {
var entries [64]overlappedEntry
- var wait, qty, flags, n, i uint32
+ var wait, n, i uint32
var errno int32
var op *net_op
var toRun gList
for i = 0; i < n; i++ {
op = entries[i].op
if op != nil && op.pd == entries[i].key {
- 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())
+ mode := op.mode
+ if mode != 'r' && mode != 'w' {
+ println("runtime: GetQueuedCompletionStatusEx returned net_op with invalid mode=", mode)
+ throw("runtime: netpoll failed")
}
- delta += handlecompletion(&toRun, op, errno, qty)
+ delta += netpollready(&toRun, op.pd, mode)
} else {
netpollWakeSig.Store(0)
if delay == 0 {
}
return toRun, delta
}
-
-func handlecompletion(toRun *gList, op *net_op, errno int32, qty uint32) int32 {
- mode := op.mode
- if mode != 'r' && mode != 'w' {
- println("runtime: GetQueuedCompletionStatusEx returned invalid mode=", mode)
- throw("runtime: netpoll failed")
- }
- op.errno = errno
- op.qty = qty
- return netpollready(toRun, op.pd, mode)
-}
// These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
_timeBeginPeriod,
_timeEndPeriod,
- _WSAGetOverlappedResult,
_ stdFunction
)
ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
)
// Function to be called by windows CreateThread
}
_RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000"))
_RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000"))
-
- ws232 := windowsLoadSystemLib(ws2_32dll[:])
- if ws232 == 0 {
- throw("ws2_32.dll not found")
- }
- _WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
- if _WSAGetOverlappedResult == nil {
- throw("WSAGetOverlappedResult not found")
- }
}
func monitorSuspendResume() {