src/pkg/net/fd_unix.go | 18 ++++++++++++++---- src/pkg/net/fd_windows.go | 9 ++++++++- src/pkg/net/sock_posix.go | 22 ++++++++-------------- diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go index b82ecd11c1abce64705833054fc18ecf4311a0e7..e22861abbda9912b6e3ca7910c1cc90d6782cff3 100644 --- a/src/pkg/net/fd_unix.go +++ b/src/pkg/net/fd_unix.go @@ -68,16 +68,19 @@ } return fd.net + ":" + ls + "->" + rs } -func (fd *netFD) connect(la, ra syscall.Sockaddr) error { +func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error { // Do not need to call fd.writeLock here, // because fd is not yet accessible to user, // so no concurrent operations are possible. - if err := fd.pd.PrepareWrite(); err != nil { - return err - } switch err := syscall.Connect(fd.sysfd, ra); err { case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: case nil, syscall.EISCONN: + if !deadline.IsZero() && deadline.Before(time.Now()) { + return errTimeout + } + if err := fd.init(); err != nil { + return err + } return nil case syscall.EINVAL: // On Solaris we can see EINVAL if the socket has @@ -91,6 +94,13 @@ } fallthrough default: return err + } + if err := fd.init(); err != nil { + return err + } + if !deadline.IsZero() { + fd.setWriteDeadline(deadline) + defer fd.setWriteDeadline(noDeadline) } for { // Performing multiple connect system calls on a diff --git a/src/pkg/net/fd_windows.go b/src/pkg/net/fd_windows.go index a1f6bc5f8148cb40fcbf45c7507da707dd5c89dd..d1129dccc47d8a857d038cf5758b794f5dacd80b 100644 --- a/src/pkg/net/fd_windows.go +++ b/src/pkg/net/fd_windows.go @@ -313,10 +313,17 @@ fd.raddr = raddr runtime.SetFinalizer(fd, (*netFD).Close) } -func (fd *netFD) connect(la, ra syscall.Sockaddr) error { +func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error { // Do not need to call fd.writeLock here, // because fd is not yet accessible to user, // so no concurrent operations are possible. + if err := fd.init(); err != nil { + return err + } + if !deadline.IsZero() { + fd.setWriteDeadline(deadline) + defer fd.setWriteDeadline(noDeadline) + } if !canUseConnectEx(fd.net) { return syscall.Connect(fd.sysfd, ra) } diff --git a/src/pkg/net/sock_posix.go b/src/pkg/net/sock_posix.go index a6ef874c9fda0b3304dd503f2c1b836d2b5e200f..c80c7d6a2f1242f9a105d63b2cae59cad68adeec 100644 --- a/src/pkg/net/sock_posix.go +++ b/src/pkg/net/sock_posix.go @@ -107,24 +107,18 @@ return os.NewSyscallError("bind", err) } } } - if err := fd.init(); err != nil { - return err - } var rsa syscall.Sockaddr if raddr != nil { if rsa, err = raddr.sockaddr(fd.family); err != nil { return err - } else if rsa != nil { - if !deadline.IsZero() { - fd.setWriteDeadline(deadline) - } - if err := fd.connect(lsa, rsa); err != nil { - return err - } - fd.isConnected = true - if !deadline.IsZero() { - fd.setWriteDeadline(noDeadline) - } + } + if err := fd.connect(lsa, rsa, deadline); err != nil { + return err + } + fd.isConnected = true + } else { + if err := fd.init(); err != nil { + return err } } lsa, _ = syscall.Getsockname(fd.sysfd)