Commit 62747bde authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: catch races between channel close and channel send in select

R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/10137043
parent 06f55f50
...@@ -186,7 +186,6 @@ runtime·chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc) ...@@ -186,7 +186,6 @@ runtime·chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
} }
runtime·lock(c); runtime·lock(c);
// TODO(dvyukov): add similar instrumentation to select.
if(raceenabled) if(raceenabled)
runtime·racereadpc(c, pc, runtime·chansend); runtime·racereadpc(c, pc, runtime·chansend);
if(c->closed) if(c->closed)
...@@ -946,6 +945,8 @@ loop: ...@@ -946,6 +945,8 @@ loop:
break; break;
case CaseSend: case CaseSend:
if(raceenabled)
runtime·racereadpc(c, cas->pc, runtime·chansend);
if(c->closed) if(c->closed)
goto sclose; goto sclose;
if(c->dataqsiz > 0) { if(c->dataqsiz > 0) {
......
...@@ -311,12 +311,35 @@ func TestRaceChanSendClose(t *testing.T) { ...@@ -311,12 +311,35 @@ func TestRaceChanSendClose(t *testing.T) {
go func() { go func() {
defer func() { defer func() {
recover() recover()
compl <- true
}() }()
c <- 1 c <- 1
}()
go func() {
time.Sleep(10 * time.Millisecond)
close(c)
compl <- true
}()
<-compl
<-compl
}
func TestRaceChanSendSelectClose(t *testing.T) {
compl := make(chan bool, 2)
c := make(chan int, 1)
c1 := make(chan int)
go func() {
defer func() {
recover()
compl <- true compl <- true
}() }()
time.Sleep(10 * time.Millisecond)
select {
case c <- 1:
case <-c1:
}
}()
go func() { go func() {
time.Sleep(1e7)
close(c) close(c)
compl <- true compl <- true
}() }()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment