diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go index 38fecb0e12d..1ede48103bc 100644 --- a/src/internal/poll/fd_windows.go +++ b/src/internal/poll/fd_windows.go @@ -77,14 +77,12 @@ type operation struct { mode int32 // fields used only by net package - buf syscall.WSABuf - msg windows.WSAMsg - sa syscall.Sockaddr - rsa *syscall.RawSockaddrAny - rsan int32 - flags uint32 - qty uint32 - bufs []syscall.WSABuf + buf syscall.WSABuf + msg windows.WSAMsg + sa syscall.Sockaddr + rsa *syscall.RawSockaddrAny + rsan int32 + bufs []syscall.WSABuf } func (o *operation) setEvent() { @@ -210,7 +208,7 @@ func (fd *FD) cancelIO(o *operation) { // It supports both synchronous and asynchronous IO. // o.qty and o.flags are set to zero before calling submit // to avoid reusing the values from a previous call. -func (fd *FD) execIO(o *operation, submit func(o *operation) error) (int, error) { +func (fd *FD) execIO(o *operation, submit func(o *operation) (uint32, error)) (int, error) { // Notify runtime netpoll about starting IO. err := fd.pd.prepare(int(o.mode), fd.isFile) if err != nil { @@ -223,9 +221,7 @@ func (fd *FD) execIO(o *operation, submit func(o *operation) error) (int, error) // event to wait for the IO to complete. o.setEvent() } - o.qty = 0 - o.flags = 0 - err = submit(o) + qty, err := submit(o) var waitErr error // Blocking operations shouldn't return ERROR_IO_PENDING. // Continue without waiting if that happens. @@ -240,9 +236,10 @@ func (fd *FD) execIO(o *operation, submit func(o *operation) error) (int, error) // before the cancellation request runs. } if fd.isFile { - err = windows.GetOverlappedResult(fd.Sysfd, &o.o, &o.qty, false) + err = windows.GetOverlappedResult(fd.Sysfd, &o.o, &qty, false) } else { - err = windows.WSAGetOverlappedResult(fd.Sysfd, &o.o, &o.qty, false, &o.flags) + var flags uint32 + err = windows.WSAGetOverlappedResult(fd.Sysfd, &o.o, &qty, false, &flags) } } switch err { @@ -266,7 +263,7 @@ func (fd *FD) execIO(o *operation, submit func(o *operation) error) (int, error) err = waitErr } } - return int(o.qty), err + return int(qty), err } // FD is a file descriptor. The net and os packages embed this type in @@ -507,8 +504,9 @@ func (fd *FD) Read(buf []byte) (int, error) { case kindFile, kindPipe: o := &fd.rop o.InitBuf(buf) - n, err = fd.execIO(o, func(o *operation) error { - return syscall.ReadFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, fd.overlapped(o)) + n, err = fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.ReadFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &qty, fd.overlapped(o)) + return qty, err }) fd.addOffset(n) switch err { @@ -523,8 +521,10 @@ func (fd *FD) Read(buf []byte) (int, error) { case kindNet: o := &fd.rop o.InitBuf(buf) - n, err = fd.execIO(o, func(o *operation) error { - return syscall.WSARecv(fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) + n, err = fd.execIO(o, func(o *operation) (qty uint32, err error) { + var flags uint32 + err = syscall.WSARecv(fd.Sysfd, &o.buf, 1, &qty, &flags, &o.o, nil) + return qty, err }) if race.Enabled { race.Acquire(unsafe.Pointer(&ioSync)) @@ -638,8 +638,9 @@ func (fd *FD) Pread(b []byte, off int64) (int, error) { o := &fd.rop o.InitBuf(b) fd.setOffset(off) - n, err := fd.execIO(o, func(o *operation) error { - return syscall.ReadFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, &o.o) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.ReadFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &qty, &o.o) + return qty, err }) if err == syscall.ERROR_HANDLE_EOF { err = io.EOF @@ -664,12 +665,14 @@ func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) - n, err := fd.execIO(o, func(o *operation) error { + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } o.rsan = int32(unsafe.Sizeof(*o.rsa)) - return syscall.WSARecvFrom(fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) + var flags uint32 + err = syscall.WSARecvFrom(fd.Sysfd, &o.buf, 1, &qty, &flags, o.rsa, &o.rsan, &o.o, nil) + return qty, err }) err = fd.eofError(n, err) if err != nil { @@ -693,12 +696,14 @@ func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) - n, err := fd.execIO(o, func(o *operation) error { + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } o.rsan = int32(unsafe.Sizeof(*o.rsa)) - return syscall.WSARecvFrom(fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) + var flags uint32 + err = syscall.WSARecvFrom(fd.Sysfd, &o.buf, 1, &qty, &flags, o.rsa, &o.rsan, &o.o, nil) + return qty, err }) err = fd.eofError(n, err) if err != nil { @@ -722,12 +727,14 @@ func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) - n, err := fd.execIO(o, func(o *operation) error { + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } o.rsan = int32(unsafe.Sizeof(*o.rsa)) - return syscall.WSARecvFrom(fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) + var flags uint32 + err = syscall.WSARecvFrom(fd.Sysfd, &o.buf, 1, &qty, &flags, o.rsa, &o.rsan, &o.o, nil) + return qty, err }) err = fd.eofError(n, err) if err != nil { @@ -763,8 +770,9 @@ func (fd *FD) Write(buf []byte) (int, error) { case kindPipe, kindFile: o := &fd.wop o.InitBuf(b) - n, err = fd.execIO(o, func(o *operation) error { - return syscall.WriteFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, fd.overlapped(o)) + n, err = fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.WriteFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &qty, fd.overlapped(o)) + return qty, err }) fd.addOffset(n) case kindNet: @@ -773,8 +781,9 @@ func (fd *FD) Write(buf []byte) (int, error) { } o := &fd.wop o.InitBuf(b) - n, err = fd.execIO(o, func(o *operation) error { - return syscall.WSASend(fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) + n, err = fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.WSASend(fd.Sysfd, &o.buf, 1, &qty, 0, &o.o, nil) + return qty, err }) } ntotal += n @@ -862,8 +871,9 @@ func (fd *FD) Pwrite(buf []byte, off int64) (int, error) { o := &fd.wop o.InitBuf(b) fd.setOffset(off + int64(ntotal)) - n, err := fd.execIO(o, func(o *operation) error { - return syscall.WriteFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, &o.o) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.WriteFile(fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &qty, &o.o) + return qty, err }) if n > 0 { ntotal += n @@ -891,8 +901,9 @@ func (fd *FD) Writev(buf *[][]byte) (int64, error) { } o := &fd.wop o.InitBufs(buf) - n, err := fd.execIO(o, func(o *operation) error { - return syscall.WSASend(fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.WSASend(fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &qty, 0, &o.o, nil) + return qty, err }) o.ClearBufs() TestHookDidWritev(n) @@ -912,8 +923,9 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { o := &fd.wop o.InitBuf(buf) o.sa = sa - n, err := fd.execIO(o, func(o *operation) error { - return syscall.WSASendto(fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.WSASendto(fd.Sysfd, &o.buf, 1, &qty, 0, o.sa, &o.o, nil) + return qty, err }) return n, err } @@ -927,8 +939,9 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { o := &fd.wop o.InitBuf(b) o.sa = sa - n, err := fd.execIO(o, func(o *operation) error { - return syscall.WSASendto(fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = syscall.WSASendto(fd.Sysfd, &o.buf, 1, &qty, 0, o.sa, &o.o, nil) + return qty, err }) ntotal += int(n) if err != nil { @@ -950,8 +963,9 @@ func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) // handle zero-byte payload o := &fd.wop o.InitBuf(buf) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendtoInet4(fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendtoInet4(fd.Sysfd, &o.buf, 1, &qty, 0, sa4, &o.o, nil) + return qty, err }) return n, err } @@ -964,8 +978,9 @@ func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) } o := &fd.wop o.InitBuf(b) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendtoInet4(fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendtoInet4(fd.Sysfd, &o.buf, 1, &qty, 0, sa4, &o.o, nil) + return qty, err }) ntotal += int(n) if err != nil { @@ -987,8 +1002,9 @@ func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) // handle zero-byte payload o := &fd.wop o.InitBuf(buf) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendtoInet6(fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendtoInet6(fd.Sysfd, &o.buf, 1, &qty, 0, sa6, &o.o, nil) + return qty, err }) return n, err } @@ -1001,8 +1017,9 @@ func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) } o := &fd.wop o.InitBuf(b) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendtoInet6(fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendtoInet6(fd.Sysfd, &o.buf, 1, &qty, 0, sa6, &o.o, nil) + return qty, err }) ntotal += int(n) if err != nil { @@ -1019,8 +1036,8 @@ func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { o := &fd.wop o.sa = ra - _, err := fd.execIO(o, func(o *operation) error { - return ConnectExFunc(fd.Sysfd, o.sa, nil, 0, nil, &o.o) + _, err := fd.execIO(o, func(o *operation) (uint32, error) { + return 0, ConnectExFunc(fd.Sysfd, o.sa, nil, 0, nil, &o.o) }) return err } @@ -1028,8 +1045,9 @@ func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) { // Submit accept request. o.rsan = int32(unsafe.Sizeof(rawsa[0])) - _, err := fd.execIO(o, func(o *operation) error { - return AcceptFunc(fd.Sysfd, s, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o) + _, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = AcceptFunc(fd.Sysfd, s, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &qty, &o.o) + return qty, err }) if err != nil { CloseFunc(s) @@ -1171,11 +1189,13 @@ func (fd *FD) RawRead(f func(uintptr) bool) error { // socket is readable. h/t https://stackoverflow.com/a/42019668/332798 o := &fd.rop o.InitBuf(nil) - _, err := fd.execIO(o, func(o *operation) error { + _, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + var flags uint32 if !fd.IsStream { - o.flags |= windows.MSG_PEEK + flags |= windows.MSG_PEEK } - return syscall.WSARecv(fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) + err = syscall.WSARecv(fd.Sysfd, &o.buf, 1, &qty, &flags, &o.o, nil) + return qty, err }) if err == windows.WSAEMSGSIZE { // expected with a 0-byte peek, ignore. @@ -1270,8 +1290,9 @@ func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.S o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) o.msg.Flags = uint32(flags) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSARecvMsg(fd.Sysfd, &o.msg, &o.qty, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSARecvMsg(fd.Sysfd, &o.msg, &qty, &o.o, nil) + return qty, err }) err = fd.eofError(n, err) var sa syscall.Sockaddr @@ -1300,8 +1321,9 @@ func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.Sockadd o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) o.msg.Flags = uint32(flags) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSARecvMsg(fd.Sysfd, &o.msg, &o.qty, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSARecvMsg(fd.Sysfd, &o.msg, &qty, &o.o, nil) + return qty, err }) err = fd.eofError(n, err) if err == nil { @@ -1329,8 +1351,9 @@ func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.Sockadd o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) o.msg.Flags = uint32(flags) - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSARecvMsg(fd.Sysfd, &o.msg, &o.qty, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSARecvMsg(fd.Sysfd, &o.msg, &qty, &o.o, nil) + return qty, err }) err = fd.eofError(n, err) if err == nil { @@ -1363,8 +1386,9 @@ func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, err o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = len } - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendMsg(fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendMsg(fd.Sysfd, &o.msg, 0, nil, &o.o, nil) + return qty, err }) return n, int(o.msg.Control.Len), err } @@ -1388,8 +1412,9 @@ func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (in len := sockaddrInet4ToRaw(o.rsa, sa) o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = len - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendMsg(fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendMsg(fd.Sysfd, &o.msg, 0, nil, &o.o, nil) + return qty, err }) return n, int(o.msg.Control.Len), err } @@ -1413,8 +1438,9 @@ func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (in len := sockaddrInet6ToRaw(o.rsa, sa) o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) o.msg.Namelen = len - n, err := fd.execIO(o, func(o *operation) error { - return windows.WSASendMsg(fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) + n, err := fd.execIO(o, func(o *operation) (qty uint32, err error) { + err = windows.WSASendMsg(fd.Sysfd, &o.msg, 0, nil, &o.o, nil) + return qty, err }) return n, int(o.msg.Control.Len), err } diff --git a/src/internal/poll/sendfile_windows.go b/src/internal/poll/sendfile_windows.go index 67e7b2e7670..a052f4a1f82 100644 --- a/src/internal/poll/sendfile_windows.go +++ b/src/internal/poll/sendfile_windows.go @@ -73,9 +73,12 @@ func SendFile(fd *FD, src uintptr, size int64) (written int64, err error, handle o.o.Offset = uint32(off) o.o.OffsetHigh = uint32(off >> 32) - n, err := fd.execIO(o, func(o *operation) error { - o.qty = uint32(chunkSize) - return syscall.TransmitFile(fd.Sysfd, hsrc, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) + n, err := fd.execIO(o, func(o *operation) (uint32, error) { + err := syscall.TransmitFile(fd.Sysfd, hsrc, uint32(chunkSize), 0, &o.o, nil, syscall.TF_WRITE_BEHIND) + if err != nil { + return 0, err + } + return uint32(chunkSize), nil }) if err != nil { return written, err, written > 0