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 | 37a5374c81491d25d723e20b33c4b05fb38f1ec5 (patch) | |
| tree | 0ae8d72fe88b97b3b22c366004daf404c63ecfc7 /src/lib | |
| parent | 1605176e25fd5f7d2136e52797a0b2fa6e1f8947 (diff) | |
| download | go-37a5374c81491d25d723e20b33c4b05fb38f1ec5.tar.xz | |
document and partially fix a race
R=r
DELTA=24 (21 added, 0 deleted, 3 changed)
OCL=27527
CL=27527
Diffstat (limited to 'src/lib')
| -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 6066bd5cd2..c098c20b20 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; |
