]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: catch races between channel close and channel send in select
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Jun 2013 18:58:04 +0000 (22:58 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 10 Jun 2013 18:58:04 +0000 (22:58 +0400)
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/10137043

src/pkg/runtime/chan.c
src/pkg/runtime/race/testdata/chan_test.go

index 403a72dc8af9cbccbf0d3682e6e0978ea38bd932..6aa9bd40e1267d66ee84b93f351d964663590f12 100644 (file)
@@ -186,7 +186,6 @@ runtime·chansend(ChanType *t, Hchan *c, byte *ep, bool *pres, void *pc)
        }
 
        runtime·lock(c);
-       // TODO(dvyukov): add similar instrumentation to select.
        if(raceenabled)
                runtime·racereadpc(c, pc, runtime·chansend);
        if(c->closed)
@@ -946,6 +945,8 @@ loop:
                        break;
 
                case CaseSend:
+                       if(raceenabled)
+                               runtime·racereadpc(c, cas->pc, runtime·chansend);
                        if(c->closed)
                                goto sclose;
                        if(c->dataqsiz > 0) {
index 2332f097eb04dd008b4191b02e48014e85ba0a44..614ba4a4e2cadc67e8922f0dee93ad96f3c22bce 100644 (file)
@@ -311,12 +311,35 @@ func TestRaceChanSendClose(t *testing.T) {
        go func() {
                defer func() {
                        recover()
+                       compl <- true
                }()
                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
+               }()
+               time.Sleep(10 * time.Millisecond)
+               select {
+               case c <- 1:
+               case <-c1:
+               }
+       }()
        go func() {
-               time.Sleep(1e7)
                close(c)
                compl <- true
        }()