net: fix possible runtime.PollDesc leak when connect or listen fails
Makes it possible to return the spent runtime.PollDesc to
runtime.pollcache descriptor pool when netFD.connect or
syscall.Listen fails.
Fixes #5219.
R=dvyukov, dave, bradfitz, adg
CC=golang-dev
https://golang.org/cl/8318044
diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go
index f52c98a..c160fae 100644
--- a/src/pkg/net/fd_unix.go
+++ b/src/pkg/net/fd_unix.go
@@ -122,12 +122,16 @@
func (fd *netFD) decref() {
fd.sysmu.Lock()
fd.sysref--
- if fd.closing && fd.sysref == 0 && fd.sysfile != nil {
+ if fd.closing && fd.sysref == 0 {
// Poller may want to unregister fd in readiness notification mechanism,
// so this must be executed before sysfile.Close().
fd.pd.Close()
- fd.sysfile.Close()
- fd.sysfile = nil
+ if fd.sysfile != nil {
+ fd.sysfile.Close()
+ fd.sysfile = nil
+ } else {
+ closesocket(fd.sysfd)
+ }
fd.sysfd = -1
}
fd.sysmu.Unlock()
diff --git a/src/pkg/net/sock_posix.go b/src/pkg/net/sock_posix.go
index e2487c8..7e6a2c0 100644
--- a/src/pkg/net/sock_posix.go
+++ b/src/pkg/net/sock_posix.go
@@ -58,7 +58,7 @@
setWriteDeadline(fd, deadline)
}
if err = fd.connect(ursa); err != nil {
- closesocket(s)
+ fd.Close()
return nil, err
}
fd.isConnected = true
diff --git a/src/pkg/net/tcpsock_posix.go b/src/pkg/net/tcpsock_posix.go
index 8133ca1..2224e6a 100644
--- a/src/pkg/net/tcpsock_posix.go
+++ b/src/pkg/net/tcpsock_posix.go
@@ -288,7 +288,7 @@
}
err = syscall.Listen(fd.sysfd, listenerBacklog)
if err != nil {
- closesocket(fd.sysfd)
+ fd.Close()
return nil, &OpError{"listen", net, laddr, err}
}
return &TCPListener{fd}, nil
diff --git a/src/pkg/net/unixsock_posix.go b/src/pkg/net/unixsock_posix.go
index 760d38f..6490cae 100644
--- a/src/pkg/net/unixsock_posix.go
+++ b/src/pkg/net/unixsock_posix.go
@@ -271,7 +271,7 @@
}
err = syscall.Listen(fd.sysfd, listenerBacklog)
if err != nil {
- closesocket(fd.sysfd)
+ fd.Close()
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
}
return &UnixListener{fd, laddr.Name}, nil