]> Cypherpunks repositories - gostls13.git/commitdiff
io: Avoid race condition in pipe.
authorIan Lance Taylor <iant@golang.org>
Wed, 30 Jun 2010 20:14:46 +0000 (13:14 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 30 Jun 2010 20:14:46 +0000 (13:14 -0700)
One goroutine started up and was waiting in rw.  Then another
goroutine decided to close the pipe.  The closing goroutine
stalled calling p.io.Lock() in pipeHalf.close.  (This happened
in gccgo).  If the closing goroutine had been able to set the
ioclosed flag, it would have gone on to tell the runner that
the pipe was closed, which would then send an EINVAL to the
goroutine sleeping in rw.  Unlocking p.io before sleeping in
rw avoids the race.

R=rsc, rsc1
CC=golang-dev
https://golang.org/cl/1682048

src/pkg/io/pipe.go

index 79221bd4978378d9b92e8628737482f141b81179..898526921fcfc8a326e5fac2cd0c4150d798b85f 100644 (file)
@@ -144,10 +144,11 @@ func (p *pipeHalf) rw(data []byte) (n int, err os.Error) {
        // Run i/o operation.
        // Check ioclosed flag under lock to make sure we're still allowed to do i/o.
        p.io.Lock()
-       defer p.io.Unlock()
        if p.ioclosed {
+               p.io.Unlock()
                return 0, os.EINVAL
        }
+       p.io.Unlock()
        p.c1 <- data
        res := <-p.c2
        return res.n, res.err