net: separate pollster initialization from network file descriptor allocation

Unlike the existing net package own pollster, runtime-integrated
network pollster on BSD variants, actually kqueue, requires a socket
that has beed passed to syscall.Listen previously for a stream
listener.

This CL separates pollDesc.Init (actually runtime_pollOpen) from newFD
to allow control of each state of sockets and adds init method to netFD
instead. Upcoming CLs will rearrange the call order of runtime-integrated
pollster and syscall functions like the following;

- For dialers that open active connections, runtime_pollOpen will be
  called in between syscall.Bind and syscall.Connect.

- For stream listeners that open passive stream connections,
  runtime_pollOpen will be called just after syscall.Listen.

- For datagram listeners that open datagram connections,
  runtime_pollOpen will be called just after syscall.Bind.

This is in preparation for runtime-integrated network pollster for BSD
variants.

Update #5199

R=dvyukov, alex.brainman, minux.ma
CC=golang-dev
https://golang.org/cl/8608044
diff --git a/src/pkg/net/fd_poll_runtime.go b/src/pkg/net/fd_poll_runtime.go
index 4f20a7e..6ae5c60 100644
--- a/src/pkg/net/fd_poll_runtime.go
+++ b/src/pkg/net/fd_poll_runtime.go
@@ -38,7 +38,11 @@
 }
 
 func (pd *pollDesc) Close() {
+	if pd.runtimeCtx == 0 {
+		return
+	}
 	runtime_pollClose(pd.runtimeCtx)
+	pd.runtimeCtx = 0
 }
 
 func (pd *pollDesc) Lock() {
@@ -53,6 +57,9 @@
 // Evict evicts fd from the pending list, unblocking any I/O running on fd.
 // Return value is whether the pollServer should be woken up.
 func (pd *pollDesc) Evict() bool {
+	if pd.runtimeCtx == 0 {
+		return false
+	}
 	runtime_pollUnblock(pd.runtimeCtx)
 	return false
 }
diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go
index 14a3187..a2a7714 100644
--- a/src/pkg/net/fd_unix.go
+++ b/src/pkg/net/fd_unix.go
@@ -55,17 +55,15 @@
 	return dial(net, addr, localAddr, ra, deadline)
 }
 
-func newFD(fd, family, sotype int, net string) (*netFD, error) {
-	netfd := &netFD{
-		sysfd:  fd,
-		family: family,
-		sotype: sotype,
-		net:    net,
+func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
+	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
+}
+
+func (fd *netFD) init() error {
+	if err := fd.pd.Init(fd); err != nil {
+		return err
 	}
-	if err := netfd.pd.Init(netfd); err != nil {
-		return nil, err
-	}
-	return netfd, nil
+	return nil
 }
 
 func (fd *netFD) setAddr(laddr, raddr Addr) {
@@ -401,6 +399,10 @@
 		closesocket(s)
 		return nil, err
 	}
+	if err = netfd.init(); err != nil {
+		fd.Close()
+		return nil, err
+	}
 	lsa, _ := syscall.Getsockname(netfd.sysfd)
 	netfd.setAddr(toAddr(lsa), toAddr(rsa))
 	return netfd, nil
diff --git a/src/pkg/net/fd_windows.go b/src/pkg/net/fd_windows.go
index 9ed99ed..974a542 100644
--- a/src/pkg/net/fd_windows.go
+++ b/src/pkg/net/fd_windows.go
@@ -242,14 +242,12 @@
 		return nil, initErr
 	}
 	onceStartServer.Do(startServer)
-	fd := &netFD{
-		sysfd:  sysfd,
-		family: family,
-		sotype: sotype,
-		net:    net,
-	}
+	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
+}
+
+func (fd *netFD) init() error {
 	if err := fd.pd.Init(fd); err != nil {
-		return nil, err
+		return err
 	}
 	fd.rop.mode = 'r'
 	fd.wop.mode = 'w'
@@ -261,7 +259,7 @@
 		fd.rop.errc = make(chan error)
 		fd.rop.errc = make(chan error)
 	}
-	return fd, nil
+	return nil
 }
 
 func (fd *netFD) setAddr(laddr, raddr Addr) {
@@ -473,6 +471,10 @@
 		closesocket(s)
 		return nil, &OpError{"accept", fd.net, fd.laddr, err}
 	}
+	if err := netfd.init(); err != nil {
+		fd.Close()
+		return nil, err
+	}
 
 	// Submit accept request.
 	o := &fd.rop
diff --git a/src/pkg/net/file_unix.go b/src/pkg/net/file_unix.go
index 1e7420c..fe01918 100644
--- a/src/pkg/net/file_unix.go
+++ b/src/pkg/net/file_unix.go
@@ -67,6 +67,10 @@
 		closesocket(fd)
 		return nil, err
 	}
+	if err := netfd.init(); err != nil {
+		netfd.Close()
+		return nil, err
+	}
 	netfd.setAddr(laddr, raddr)
 	return netfd, nil
 }
diff --git a/src/pkg/net/sock_posix.go b/src/pkg/net/sock_posix.go
index 1b66d37..5c6ca8d 100644
--- a/src/pkg/net/sock_posix.go
+++ b/src/pkg/net/sock_posix.go
@@ -93,6 +93,10 @@
 		closesocket(s)
 		return nil, err
 	}
+	if err := fd.init(); err != nil {
+		fd.Close()
+		return nil, err
+	}
 
 	var rsa syscall.Sockaddr
 	if raddr != nil {