aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/fd_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/fd_windows.go')
-rw-r--r--libgo/go/net/fd_windows.go41
1 files changed, 30 insertions, 11 deletions
diff --git a/libgo/go/net/fd_windows.go b/libgo/go/net/fd_windows.go
index 205daff9e46..fd50d772d60 100644
--- a/libgo/go/net/fd_windows.go
+++ b/libgo/go/net/fd_windows.go
@@ -5,6 +5,7 @@
package net
import (
+ "internal/race"
"os"
"runtime"
"sync"
@@ -208,7 +209,7 @@ func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro
s.req <- ioSrvReq{o, nil}
<-o.errc
}
- // Wait for cancellation to complete.
+ // Wait for cancelation to complete.
fd.pd.WaitCanceled(int(o.mode))
if o.errno != 0 {
err = syscall.Errno(o.errno)
@@ -217,8 +218,8 @@ func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro
}
return 0, err
}
- // We issued cancellation request. But, it seems, IO operation succeeded
- // before cancellation request run. We need to treat IO operation as
+ // We issued a cancelation request. But, it seems, IO operation succeeded
+ // before the cancelation request run. We need to treat the IO operation as
// succeeded (the bytes are actually sent/recv from network).
return int(o.qty), nil
}
@@ -319,7 +320,7 @@ func (fd *netFD) setAddr(laddr, raddr Addr) {
runtime.SetFinalizer(fd, (*netFD).Close)
}
-func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time, cancel <-chan struct{}) error {
// Do not need to call fd.writeLock here,
// because fd is not yet accessible to user,
// so no concurrent operations are possible.
@@ -350,14 +351,32 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
// Call ConnectEx API.
o := &fd.wop
o.sa = ra
+ if cancel != nil {
+ done := make(chan struct{})
+ defer close(done)
+ go func() {
+ select {
+ case <-cancel:
+ // Force the runtime's poller to immediately give
+ // up waiting for writability.
+ fd.setWriteDeadline(aLongTimeAgo)
+ case <-done:
+ }
+ }()
+ }
_, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error {
return connectExFunc(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
})
if err != nil {
- if _, ok := err.(syscall.Errno); ok {
- err = os.NewSyscallError("connectex", err)
+ select {
+ case <-cancel:
+ return errCanceled
+ default:
+ if _, ok := err.(syscall.Errno); ok {
+ err = os.NewSyscallError("connectex", err)
+ }
+ return err
}
- return err
}
// Refresh socket properties.
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))))
@@ -461,8 +480,8 @@ func (fd *netFD) Read(buf []byte) (int, error) {
n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
})
- if raceenabled {
- raceAcquire(unsafe.Pointer(&ioSync))
+ if race.Enabled {
+ race.Acquire(unsafe.Pointer(&ioSync))
}
err = fd.eofError(n, err)
if _, ok := err.(syscall.Errno); ok {
@@ -504,8 +523,8 @@ func (fd *netFD) Write(buf []byte) (int, error) {
return 0, err
}
defer fd.writeUnlock()
- if raceenabled {
- raceReleaseMerge(unsafe.Pointer(&ioSync))
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
}
o := &fd.wop
o.InitBuf(buf)