diff options
author | Russ Cox <rsc@golang.org> | 2009-04-15 19:01:48 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-04-15 19:01:48 -0700 |
commit | 6b05ff19c85462355a5fd666d38a40eab25d6c90 (patch) | |
tree | 0ae8d72fe88b97b3b22c366004daf404c63ecfc7 | |
parent | ddbbc6c2afddf002788bdd9076698ad69a683fd2 (diff) | |
download | golang-6b05ff19c85462355a5fd666d38a40eab25d6c90.tar.gz |
document and partially fix a race
R=r
DELTA=24 (21 added, 0 deleted, 3 changed)
OCL=27527
CL=27527
-rw-r--r-- | src/lib/net/fd.go | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/lib/net/fd.go b/src/lib/net/fd.go index 6066bd5cd..c098c20b2 100644 --- a/src/lib/net/fd.go +++ b/src/lib/net/fd.go @@ -126,13 +126,34 @@ func newPollServer() (s *pollServer, err *os.Error) { } func (s *pollServer) AddFD(fd *netFD, mode int) { - if err := s.poll.AddFD(fd.fd, mode, false); err != nil { - panicln("pollServer AddFD ", fd.fd, ": ", err.String(), "\n"); + // TODO(rsc): This check handles a race between + // one goroutine reading and another one closing, + // but it doesn't solve the race completely: + // it still could happen that one goroutine closes + // but we read fd.fd before it does, and then + // another goroutine creates a new open file with + // that fd, which we'd now be referring to. + // The fix is probably to send the Close call + // through the poll server too, except that + // not all Reads and Writes go through the poll + // server even now. + intfd := fd.fd; + if intfd < 0 { + // fd closed underfoot + if mode == 'r' { + fd.cr <- fd + } else { + fd.cw <- fd + } + return + } + if err := s.poll.AddFD(intfd, mode, false); err != nil { + panicln("pollServer AddFD ", intfd, ": ", err.String(), "\n"); return } var t int64; - key := fd.fd << 1; + key := intfd << 1; if mode == 'r' { fd.ncr++; t = fd.rdeadline; |