aboutsummaryrefslogtreecommitdiff
path: root/src/lib/net
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-02-15 19:35:52 -0800
committerRuss Cox <rsc@golang.org>2009-02-15 19:35:52 -0800
commit91ceda5c18fdf7c7512b0a36725d9d5cf1c2b23f (patch)
tree9600ec63eb31a171bc1f911505eae0806b9d33d5 /src/lib/net
parent97dcc68f1ec4202b467210dcd2607c7630bb9d6e (diff)
downloadgo-91ceda5c18fdf7c7512b0a36725d9d5cf1c2b23f.tar.xz
add os.ForkExec, os.Exec, os.Wait, exec.OpenCmd.
as thread-safe as possible, given the surrounding system. add stub RWLock implementation. R=r DELTA=852 (834 added, 6 deleted, 12 changed) OCL=25046 CL=25053
Diffstat (limited to 'src/lib/net')
-rw-r--r--src/lib/net/fd.go9
-rw-r--r--src/lib/net/net.go5
2 files changed, 14 insertions, 0 deletions
diff --git a/src/lib/net/fd.go b/src/lib/net/fd.go
index 1ec0d8af9e..0c7770c77f 100644
--- a/src/lib/net/fd.go
+++ b/src/lib/net/fd.go
@@ -280,17 +280,26 @@ func (fd *netFD) Accept(sa *syscall.Sockaddr) (nfd *netFD, err *os.Error) {
return nil, os.EINVAL
}
+ // See ../syscall/exec.go for description of ForkLock.
+ // It is okay to hold the lock across syscall.Accept
+ // because we have put fd.fd into non-blocking mode.
+ syscall.ForkLock.RLock();
var s, e int64;
for {
s, e = syscall.Accept(fd.fd, sa);
if e != syscall.EAGAIN {
break;
}
+ syscall.ForkLock.RUnlock();
pollserver.WaitRead(fd);
+ syscall.ForkLock.RLock();
}
if e != 0 {
+ syscall.ForkLock.RUnlock();
return nil, os.ErrnoToError(e)
}
+ syscall.CloseOnExec(s);
+ syscall.ForkLock.RUnlock();
raddr, err1 := sockaddrToHostPort(sa);
if err1 != nil {
diff --git a/src/lib/net/net.go b/src/lib/net/net.go
index b81e99268a..db708191b1 100644
--- a/src/lib/net/net.go
+++ b/src/lib/net/net.go
@@ -143,10 +143,15 @@ func boolint(b bool) int {
func socket(net, laddr, raddr string, f, p, t int64, la, ra *syscall.Sockaddr)
(fd *netFD, err *os.Error)
{
+ // See ../syscall/exec.go for description of ForkLock.
+ syscall.ForkLock.RLock();
s, e := syscall.Socket(f, p, t);
if e != 0 {
+ syscall.ForkLock.RUnlock();
return nil, os.ErrnoToError(e)
}
+ syscall.CloseOnExec(s);
+ syscall.ForkLock.RUnlock();
// Allow reuse of recently-used addresses.
syscall.Setsockopt_int(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1);