]> Cypherpunks repositories - gostls13.git/commitdiff
net: fix memory leak on unix
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 30 Jul 2013 15:47:16 +0000 (19:47 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 30 Jul 2013 15:47:16 +0000 (19:47 +0400)
If netFD is closed by finalizer, runtime netpoll descriptor is not freed.

R=golang-dev, dave, alex.brainman
CC=golang-dev
https://golang.org/cl/12037043

src/pkg/net/fd_unix.go

index 4012e36d379222699986c9624f53219672b83d6d..5f8a6705df5f7fa0046c2eeb6e1909a8a1b1a0f5 100644 (file)
@@ -9,6 +9,7 @@ package net
 import (
        "io"
        "os"
+       "runtime"
        "sync"
        "syscall"
        "time"
@@ -29,7 +30,6 @@ type netFD struct {
        family      int
        sotype      int
        isConnected bool
-       sysfile     *os.File
        net         string
        laddr       Addr
        raddr       Addr
@@ -70,7 +70,7 @@ func newFD(fd, family, sotype int, net string) (*netFD, error) {
 func (fd *netFD) setAddr(laddr, raddr Addr) {
        fd.laddr = laddr
        fd.raddr = raddr
-       fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net)
+       runtime.SetFinalizer(fd, (*netFD).Close)
 }
 
 func (fd *netFD) name() string {
@@ -129,15 +129,11 @@ func (fd *netFD) decref() {
        fd.sysref--
        if fd.closing && fd.sysref == 0 {
                // Poller may want to unregister fd in readiness notification mechanism,
-               // so this must be executed before sysfile.Close().
+               // so this must be executed before closesocket.
                fd.pd.Close()
-               if fd.sysfile != nil {
-                       fd.sysfile.Close()
-                       fd.sysfile = nil
-               } else {
-                       closesocket(fd.sysfd)
-               }
+               closesocket(fd.sysfd)
                fd.sysfd = -1
+               runtime.SetFinalizer(fd, nil)
        }
        fd.sysmu.Unlock()
 }