Commit e13341ed authored by Mikio Hara's avatar Mikio Hara

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
parent 4d5affd0
......@@ -122,12 +122,16 @@ func (fd *netFD) incref(closing bool) error {
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()
......
......@@ -58,7 +58,7 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr,
setWriteDeadline(fd, deadline)
}
if err = fd.connect(ursa); err != nil {
closesocket(s)
fd.Close()
return nil, err
}
fd.isConnected = true
......
......@@ -288,7 +288,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
}
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
......
......@@ -271,7 +271,7 @@ func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
}
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment