mirror of
https://github.com/golang/go
synced 2024-11-25 08:07:57 -07:00
io: Avoid race condition in pipe.
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
This commit is contained in:
parent
d3c3c15b17
commit
7c1be45f58
@ -144,10 +144,11 @@ func (p *pipeHalf) rw(data []byte) (n int, err os.Error) {
|
|||||||
// Run i/o operation.
|
// Run i/o operation.
|
||||||
// Check ioclosed flag under lock to make sure we're still allowed to do i/o.
|
// Check ioclosed flag under lock to make sure we're still allowed to do i/o.
|
||||||
p.io.Lock()
|
p.io.Lock()
|
||||||
defer p.io.Unlock()
|
|
||||||
if p.ioclosed {
|
if p.ioclosed {
|
||||||
|
p.io.Unlock()
|
||||||
return 0, os.EINVAL
|
return 0, os.EINVAL
|
||||||
}
|
}
|
||||||
|
p.io.Unlock()
|
||||||
p.c1 <- data
|
p.c1 <- data
|
||||||
res := <-p.c2
|
res := <-p.c2
|
||||||
return res.n, res.err
|
return res.n, res.err
|
||||||
|
Loading…
Reference in New Issue
Block a user