net: use closesocket api instead of CloseHandle on Windows
thanks to piotrnar for the original CL.
Fixes #1371.
R=rsc
CC=golang-dev
https://golang.org/cl/3834042
diff --git a/src/pkg/net/fd.go b/src/pkg/net/fd.go
index 5adaf1d..5ec9184 100644
--- a/src/pkg/net/fd.go
+++ b/src/pkg/net/fd.go
@@ -606,3 +606,7 @@
return os.NewFile(ns, fd.sysfile.Name()), nil
}
+
+func closesocket(s int) (errno int) {
+ return syscall.Close(s)
+}
diff --git a/src/pkg/net/fd_windows.go b/src/pkg/net/fd_windows.go
index 64eed4a..72685d6 100644
--- a/src/pkg/net/fd_windows.go
+++ b/src/pkg/net/fd_windows.go
@@ -9,6 +9,7 @@
"sync"
"syscall"
"unsafe"
+ "runtime"
)
// BUG(brainman): The Windows implementation does not implement SetTimeout.
@@ -28,15 +29,14 @@
closing bool
// immutable until Close
- sysfd int
- family int
- proto int
- sysfile *os.File
- cr chan *ioResult
- cw chan *ioResult
- net string
- laddr Addr
- raddr Addr
+ sysfd int
+ family int
+ proto int
+ cr chan *ioResult
+ cw chan *ioResult
+ net string
+ laddr Addr
+ raddr Addr
// owned by client
rdeadline_delta int64
@@ -149,14 +149,7 @@
laddr: laddr,
raddr: raddr,
}
- var ls, rs string
- if laddr != nil {
- ls = laddr.String()
- }
- if raddr != nil {
- rs = raddr.String()
- }
- f.sysfile = os.NewFile(fd, net+":"+ls+"->"+rs)
+ runtime.SetFinalizer(f, (*netFD).Close)
return f, nil
}
@@ -178,15 +171,16 @@
// can handle the extra OS processes. Otherwise we'll need to
// use the pollserver for Close too. Sigh.
syscall.SetNonblock(fd.sysfd, false)
- fd.sysfile.Close()
- fd.sysfile = nil
+ closesocket(fd.sysfd)
fd.sysfd = -1
+ // no need for a finalizer anymore
+ runtime.SetFinalizer(fd, nil)
}
fd.sysmu.Unlock()
}
func (fd *netFD) Close() os.Error {
- if fd == nil || fd.sysfile == nil {
+ if fd == nil || fd.sysfd == -1 {
return os.EINVAL
}
@@ -213,7 +207,7 @@
defer fd.rio.Unlock()
fd.incref()
defer fd.decref()
- if fd.sysfile == nil {
+ if fd.sysfd == -1 {
return 0, os.EINVAL
}
// Submit receive request.
@@ -253,7 +247,7 @@
defer fd.rio.Unlock()
fd.incref()
defer fd.decref()
- if fd.sysfile == nil {
+ if fd.sysfd == -1 {
return 0, nil, os.EINVAL
}
// Submit receive request.
@@ -290,7 +284,7 @@
defer fd.wio.Unlock()
fd.incref()
defer fd.decref()
- if fd.sysfile == nil {
+ if fd.sysfd == -1 {
return 0, os.EINVAL
}
// Submit send request.
@@ -326,7 +320,7 @@
defer fd.wio.Unlock()
fd.incref()
defer fd.decref()
- if fd.sysfile == nil {
+ if fd.sysfd == -1 {
return 0, os.EINVAL
}
// Submit send request.
@@ -352,7 +346,7 @@
}
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
- if fd == nil || fd.sysfile == nil {
+ if fd == nil || fd.sysfd == -1 {
return nil, os.EINVAL
}
fd.incref()
@@ -387,21 +381,21 @@
case syscall.ERROR_IO_PENDING:
// IO started, and we have to wait for it's completion.
default:
- syscall.Close(s)
+ closesocket(s)
return nil, &OpError{"AcceptEx", fd.net, fd.laddr, os.Errno(e)}
}
// Wait for peer connection.
r := <-pckt.c
if r.errno != 0 {
- syscall.Close(s)
+ closesocket(s)
return nil, &OpError{"AcceptEx", fd.net, fd.laddr, os.Errno(r.errno)}
}
// Inherit properties of the listening socket.
e = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, fd.sysfd)
if e != 0 {
- syscall.Close(s)
+ closesocket(s)
return nil, &OpError{"Setsockopt", fd.net, fd.laddr, os.Errno(r.errno)}
}
@@ -422,17 +416,14 @@
laddr: laddr,
raddr: raddr,
}
- var ls, rs string
- if laddr != nil {
- ls = laddr.String()
- }
- if raddr != nil {
- rs = raddr.String()
- }
- f.sysfile = os.NewFile(s, fd.net+":"+ls+"->"+rs)
+ runtime.SetFinalizer(f, (*netFD).Close)
return f, nil
}
+func closesocket(s int) (errno int) {
+ return syscall.Closesocket(int32(s))
+}
+
func init() {
var d syscall.WSAData
e := syscall.WSAStartup(uint32(0x101), &d)
diff --git a/src/pkg/net/ipsock.go b/src/pkg/net/ipsock.go
index dd796bc..4ba6a55 100644
--- a/src/pkg/net/ipsock.go
+++ b/src/pkg/net/ipsock.go
@@ -24,7 +24,7 @@
}
fd, e := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
if fd >= 0 {
- syscall.Close(fd)
+ closesocket(fd)
}
return e == 0
}
diff --git a/src/pkg/net/sock.go b/src/pkg/net/sock.go
index 3e105ad..8ad3548 100644
--- a/src/pkg/net/sock.go
+++ b/src/pkg/net/sock.go
@@ -47,7 +47,7 @@
if la != nil {
e = syscall.Bind(s, la)
if e != 0 {
- syscall.Close(s)
+ closesocket(s)
return nil, os.Errno(e)
}
}
@@ -55,7 +55,7 @@
if ra != nil {
e = syscall.Connect(s, ra)
if e != 0 {
- syscall.Close(s)
+ closesocket(s)
return nil, os.Errno(e)
}
}
@@ -67,7 +67,7 @@
fd, err = newFD(s, f, p, net, laddr, raddr)
if err != nil {
- syscall.Close(s)
+ closesocket(s)
return nil, err
}
diff --git a/src/pkg/net/tcpsock.go b/src/pkg/net/tcpsock.go
index b0cb8f9..a4bca11 100644
--- a/src/pkg/net/tcpsock.go
+++ b/src/pkg/net/tcpsock.go
@@ -244,7 +244,7 @@
}
errno := syscall.Listen(fd.sysfd, listenBacklog())
if errno != 0 {
- syscall.Close(fd.sysfd)
+ closesocket(fd.sysfd)
return nil, &OpError{"listen", "tcp", laddr, os.Errno(errno)}
}
l = new(TCPListener)
diff --git a/src/pkg/net/unixsock.go b/src/pkg/net/unixsock.go
index 1c15e5e..2521969 100644
--- a/src/pkg/net/unixsock.go
+++ b/src/pkg/net/unixsock.go
@@ -342,7 +342,7 @@
}
e1 := syscall.Listen(fd.sysfd, 8) // listenBacklog());
if e1 != 0 {
- syscall.Close(fd.sysfd)
+ closesocket(fd.sysfd)
return nil, &OpError{Op: "listen", Net: "unix", Addr: laddr, Error: os.Errno(e1)}
}
return &UnixListener{fd, laddr.Name}, nil