]> Cypherpunks repositories - gostls13.git/commitdiff
net: prepare connect() for new network poller
authorDmitriy Vyukov <dvyukov@google.com>
Thu, 14 Mar 2013 06:32:42 +0000 (10:32 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Thu, 14 Mar 2013 06:32:42 +0000 (10:32 +0400)
The problem is that new network poller can have spurious
rediness notifications. This implementation ensures that
the socket is actually connected.

R=golang-dev, rsc, akumar
CC=golang-dev
https://golang.org/cl/7785043

src/pkg/net/fd_unix.go

index 5621927dc382e8812dd638f3d03910dada415224..cc5a030acbc24bf21fe1dbef850fd63a18e5b078 100644 (file)
@@ -86,21 +86,19 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error {
        if err := fd.pd.PrepareWrite(); err != nil {
                return err
        }
-       err := syscall.Connect(fd.sysfd, ra)
-       if err == syscall.EINPROGRESS {
-               if err = fd.pd.WaitWrite(); err != nil {
-                       return err
+       for {
+               err := syscall.Connect(fd.sysfd, ra)
+               if err == nil || err == syscall.EISCONN {
+                       break
                }
-               var e int
-               e, err = syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
-               if err != nil {
-                       return os.NewSyscallError("getsockopt", err)
+               if err != syscall.EINPROGRESS && err != syscall.EALREADY && err != syscall.EINTR {
+                       return err
                }
-               if e != 0 {
-                       err = syscall.Errno(e)
+               if err = fd.pd.WaitWrite(); err != nil {
+                       return err
                }
        }
-       return err
+       return nil
 }
 
 // Add a reference to this fd.