Home | History | Annotate | Download | only in testdata
      1 // Copyright 2011 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package race_test
      6 
      7 import (
      8 	"runtime"
      9 	"testing"
     10 	"time"
     11 )
     12 
     13 func TestNoRaceChanSync(t *testing.T) {
     14 	v := 0
     15 	c := make(chan int)
     16 	go func() {
     17 		v = 1
     18 		c <- 0
     19 	}()
     20 	<-c
     21 	v = 2
     22 }
     23 
     24 func TestNoRaceChanSyncRev(t *testing.T) {
     25 	v := 0
     26 	c := make(chan int)
     27 	go func() {
     28 		c <- 0
     29 		v = 2
     30 	}()
     31 	v = 1
     32 	<-c
     33 }
     34 
     35 func TestNoRaceChanAsync(t *testing.T) {
     36 	v := 0
     37 	c := make(chan int, 10)
     38 	go func() {
     39 		v = 1
     40 		c <- 0
     41 	}()
     42 	<-c
     43 	v = 2
     44 }
     45 
     46 func TestRaceChanAsyncRev(t *testing.T) {
     47 	v := 0
     48 	c := make(chan int, 10)
     49 	go func() {
     50 		c <- 0
     51 		v = 1
     52 	}()
     53 	v = 2
     54 	<-c
     55 }
     56 
     57 func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
     58 	v := 0
     59 	c := make(chan int, 10)
     60 	go func() {
     61 		v = 1
     62 		close(c)
     63 	}()
     64 	func() {
     65 		defer func() {
     66 			recover()
     67 			v = 2
     68 		}()
     69 		<-c
     70 	}()
     71 }
     72 
     73 func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
     74 	v := 0
     75 	c := make(chan int, 10)
     76 	go func() {
     77 		v = 1
     78 		close(c)
     79 	}()
     80 	_, _ = <-c
     81 	v = 2
     82 }
     83 
     84 func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
     85 	v := 0
     86 	c := make(chan int, 10)
     87 	go func() {
     88 		v = 1
     89 		close(c)
     90 	}()
     91 	for range c {
     92 	}
     93 	v = 2
     94 }
     95 
     96 func TestNoRaceChanSyncCloseRecv(t *testing.T) {
     97 	v := 0
     98 	c := make(chan int)
     99 	go func() {
    100 		v = 1
    101 		close(c)
    102 	}()
    103 	func() {
    104 		defer func() {
    105 			recover()
    106 			v = 2
    107 		}()
    108 		<-c
    109 	}()
    110 }
    111 
    112 func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
    113 	v := 0
    114 	c := make(chan int)
    115 	go func() {
    116 		v = 1
    117 		close(c)
    118 	}()
    119 	_, _ = <-c
    120 	v = 2
    121 }
    122 
    123 func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
    124 	v := 0
    125 	c := make(chan int)
    126 	go func() {
    127 		v = 1
    128 		close(c)
    129 	}()
    130 	for range c {
    131 	}
    132 	v = 2
    133 }
    134 
    135 func TestRaceChanSyncCloseSend(t *testing.T) {
    136 	v := 0
    137 	c := make(chan int)
    138 	go func() {
    139 		v = 1
    140 		close(c)
    141 	}()
    142 	func() {
    143 		defer func() {
    144 			recover()
    145 		}()
    146 		c <- 0
    147 	}()
    148 	v = 2
    149 }
    150 
    151 func TestRaceChanAsyncCloseSend(t *testing.T) {
    152 	v := 0
    153 	c := make(chan int, 10)
    154 	go func() {
    155 		v = 1
    156 		close(c)
    157 	}()
    158 	func() {
    159 		defer func() {
    160 			recover()
    161 		}()
    162 		for {
    163 			c <- 0
    164 		}
    165 	}()
    166 	v = 2
    167 }
    168 
    169 func TestRaceChanCloseClose(t *testing.T) {
    170 	compl := make(chan bool, 2)
    171 	v1 := 0
    172 	v2 := 0
    173 	c := make(chan int)
    174 	go func() {
    175 		defer func() {
    176 			if recover() != nil {
    177 				v2 = 2
    178 			}
    179 			compl <- true
    180 		}()
    181 		v1 = 1
    182 		close(c)
    183 	}()
    184 	go func() {
    185 		defer func() {
    186 			if recover() != nil {
    187 				v1 = 2
    188 			}
    189 			compl <- true
    190 		}()
    191 		v2 = 1
    192 		close(c)
    193 	}()
    194 	<-compl
    195 	<-compl
    196 }
    197 
    198 func TestRaceChanSendLen(t *testing.T) {
    199 	v := 0
    200 	c := make(chan int, 10)
    201 	go func() {
    202 		v = 1
    203 		c <- 1
    204 	}()
    205 	for len(c) == 0 {
    206 		runtime.Gosched()
    207 	}
    208 	v = 2
    209 }
    210 
    211 func TestRaceChanRecvLen(t *testing.T) {
    212 	v := 0
    213 	c := make(chan int, 10)
    214 	c <- 1
    215 	go func() {
    216 		v = 1
    217 		<-c
    218 	}()
    219 	for len(c) != 0 {
    220 		runtime.Gosched()
    221 	}
    222 	v = 2
    223 }
    224 
    225 func TestRaceChanSendSend(t *testing.T) {
    226 	compl := make(chan bool, 2)
    227 	v1 := 0
    228 	v2 := 0
    229 	c := make(chan int, 1)
    230 	go func() {
    231 		v1 = 1
    232 		select {
    233 		case c <- 1:
    234 		default:
    235 			v2 = 2
    236 		}
    237 		compl <- true
    238 	}()
    239 	go func() {
    240 		v2 = 1
    241 		select {
    242 		case c <- 1:
    243 		default:
    244 			v1 = 2
    245 		}
    246 		compl <- true
    247 	}()
    248 	<-compl
    249 	<-compl
    250 }
    251 
    252 func TestNoRaceChanPtr(t *testing.T) {
    253 	type msg struct {
    254 		x int
    255 	}
    256 	c := make(chan *msg)
    257 	go func() {
    258 		c <- &msg{1}
    259 	}()
    260 	m := <-c
    261 	m.x = 2
    262 }
    263 
    264 func TestRaceChanWrongSend(t *testing.T) {
    265 	v1 := 0
    266 	v2 := 0
    267 	c := make(chan int, 2)
    268 	go func() {
    269 		v1 = 1
    270 		c <- 1
    271 	}()
    272 	go func() {
    273 		v2 = 2
    274 		c <- 2
    275 	}()
    276 	time.Sleep(1e7)
    277 	if <-c == 1 {
    278 		v2 = 3
    279 	} else {
    280 		v1 = 3
    281 	}
    282 }
    283 
    284 func TestRaceChanWrongClose(t *testing.T) {
    285 	v1 := 0
    286 	v2 := 0
    287 	c := make(chan int, 1)
    288 	go func() {
    289 		defer func() {
    290 			recover()
    291 		}()
    292 		v1 = 1
    293 		c <- 1
    294 	}()
    295 	go func() {
    296 		time.Sleep(1e7)
    297 		v2 = 2
    298 		close(c)
    299 	}()
    300 	time.Sleep(2e7)
    301 	if _, who := <-c; who {
    302 		v2 = 2
    303 	} else {
    304 		v1 = 2
    305 	}
    306 }
    307 
    308 func TestRaceChanSendClose(t *testing.T) {
    309 	compl := make(chan bool, 2)
    310 	c := make(chan int, 1)
    311 	go func() {
    312 		defer func() {
    313 			recover()
    314 			compl <- true
    315 		}()
    316 		c <- 1
    317 	}()
    318 	go func() {
    319 		time.Sleep(10 * time.Millisecond)
    320 		close(c)
    321 		compl <- true
    322 	}()
    323 	<-compl
    324 	<-compl
    325 }
    326 
    327 func TestRaceChanSendSelectClose(t *testing.T) {
    328 	compl := make(chan bool, 2)
    329 	c := make(chan int, 1)
    330 	c1 := make(chan int)
    331 	go func() {
    332 		defer func() {
    333 			recover()
    334 			compl <- true
    335 		}()
    336 		time.Sleep(10 * time.Millisecond)
    337 		select {
    338 		case c <- 1:
    339 		case <-c1:
    340 		}
    341 	}()
    342 	go func() {
    343 		close(c)
    344 		compl <- true
    345 	}()
    346 	<-compl
    347 	<-compl
    348 }
    349 
    350 func TestRaceSelectReadWriteAsync(t *testing.T) {
    351 	done := make(chan bool)
    352 	x := 0
    353 	c1 := make(chan int, 10)
    354 	c2 := make(chan int, 10)
    355 	c3 := make(chan int)
    356 	c2 <- 1
    357 	go func() {
    358 		select {
    359 		case c1 <- x: // read of x races with...
    360 		case c3 <- 1:
    361 		}
    362 		done <- true
    363 	}()
    364 	select {
    365 	case x = <-c2: // ... write to x here
    366 	case c3 <- 1:
    367 	}
    368 	<-done
    369 }
    370 
    371 func TestRaceSelectReadWriteSync(t *testing.T) {
    372 	done := make(chan bool)
    373 	x := 0
    374 	c1 := make(chan int)
    375 	c2 := make(chan int)
    376 	c3 := make(chan int)
    377 	// make c1 and c2 ready for communication
    378 	go func() {
    379 		<-c1
    380 	}()
    381 	go func() {
    382 		c2 <- 1
    383 	}()
    384 	go func() {
    385 		select {
    386 		case c1 <- x: // read of x races with...
    387 		case c3 <- 1:
    388 		}
    389 		done <- true
    390 	}()
    391 	select {
    392 	case x = <-c2: // ... write to x here
    393 	case c3 <- 1:
    394 	}
    395 	<-done
    396 }
    397 
    398 func TestNoRaceSelectReadWriteAsync(t *testing.T) {
    399 	done := make(chan bool)
    400 	x := 0
    401 	c1 := make(chan int)
    402 	c2 := make(chan int)
    403 	go func() {
    404 		select {
    405 		case c1 <- x: // read of x does not race with...
    406 		case c2 <- 1:
    407 		}
    408 		done <- true
    409 	}()
    410 	select {
    411 	case x = <-c1: // ... write to x here
    412 	case c2 <- 1:
    413 	}
    414 	<-done
    415 }
    416 
    417 func TestRaceChanReadWriteAsync(t *testing.T) {
    418 	done := make(chan bool)
    419 	c1 := make(chan int, 10)
    420 	c2 := make(chan int, 10)
    421 	c2 <- 10
    422 	x := 0
    423 	go func() {
    424 		c1 <- x // read of x races with...
    425 		done <- true
    426 	}()
    427 	x = <-c2 // ... write to x here
    428 	<-done
    429 }
    430 
    431 func TestRaceChanReadWriteSync(t *testing.T) {
    432 	done := make(chan bool)
    433 	c1 := make(chan int)
    434 	c2 := make(chan int)
    435 	// make c1 and c2 ready for communication
    436 	go func() {
    437 		<-c1
    438 	}()
    439 	go func() {
    440 		c2 <- 10
    441 	}()
    442 	x := 0
    443 	go func() {
    444 		c1 <- x // read of x races with...
    445 		done <- true
    446 	}()
    447 	x = <-c2 // ... write to x here
    448 	<-done
    449 }
    450 
    451 func TestNoRaceChanReadWriteAsync(t *testing.T) {
    452 	done := make(chan bool)
    453 	c1 := make(chan int, 10)
    454 	x := 0
    455 	go func() {
    456 		c1 <- x // read of x does not race with...
    457 		done <- true
    458 	}()
    459 	x = <-c1 // ... write to x here
    460 	<-done
    461 }
    462 
    463 func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
    464 	type Task struct {
    465 		f    func()
    466 		done chan bool
    467 	}
    468 
    469 	queue := make(chan Task)
    470 
    471 	go func() {
    472 		t := <-queue
    473 		t.f()
    474 		t.done <- true
    475 	}()
    476 
    477 	doit := func(f func()) {
    478 		done := make(chan bool, 1)
    479 		queue <- Task{f, done}
    480 		<-done
    481 	}
    482 
    483 	x := 0
    484 	doit(func() {
    485 		x = 1
    486 	})
    487 	_ = x
    488 }
    489 
    490 func TestRaceChanItselfSend(t *testing.T) {
    491 	compl := make(chan bool, 1)
    492 	c := make(chan int, 10)
    493 	go func() {
    494 		c <- 0
    495 		compl <- true
    496 	}()
    497 	c = make(chan int, 20)
    498 	<-compl
    499 }
    500 
    501 func TestRaceChanItselfRecv(t *testing.T) {
    502 	compl := make(chan bool, 1)
    503 	c := make(chan int, 10)
    504 	c <- 1
    505 	go func() {
    506 		<-c
    507 		compl <- true
    508 	}()
    509 	time.Sleep(1e7)
    510 	c = make(chan int, 20)
    511 	<-compl
    512 }
    513 
    514 func TestRaceChanItselfNil(t *testing.T) {
    515 	c := make(chan int, 10)
    516 	go func() {
    517 		c <- 0
    518 	}()
    519 	time.Sleep(1e7)
    520 	c = nil
    521 	_ = c
    522 }
    523 
    524 func TestRaceChanItselfClose(t *testing.T) {
    525 	compl := make(chan bool, 1)
    526 	c := make(chan int)
    527 	go func() {
    528 		close(c)
    529 		compl <- true
    530 	}()
    531 	c = make(chan int)
    532 	<-compl
    533 }
    534 
    535 func TestRaceChanItselfLen(t *testing.T) {
    536 	compl := make(chan bool, 1)
    537 	c := make(chan int)
    538 	go func() {
    539 		_ = len(c)
    540 		compl <- true
    541 	}()
    542 	c = make(chan int)
    543 	<-compl
    544 }
    545 
    546 func TestRaceChanItselfCap(t *testing.T) {
    547 	compl := make(chan bool, 1)
    548 	c := make(chan int)
    549 	go func() {
    550 		_ = cap(c)
    551 		compl <- true
    552 	}()
    553 	c = make(chan int)
    554 	<-compl
    555 }
    556 
    557 func TestRaceChanCloseLen(t *testing.T) {
    558 	v := 0
    559 	c := make(chan int, 10)
    560 	c <- 0
    561 	go func() {
    562 		v = 1
    563 		close(c)
    564 	}()
    565 	time.Sleep(1e7)
    566 	_ = len(c)
    567 	v = 2
    568 }
    569 
    570 func TestRaceChanCloseSend(t *testing.T) {
    571 	compl := make(chan bool, 1)
    572 	c := make(chan int, 10)
    573 	go func() {
    574 		close(c)
    575 		compl <- true
    576 	}()
    577 	c <- 0
    578 	<-compl
    579 }
    580 
    581 func TestNoRaceChanMutex(t *testing.T) {
    582 	done := make(chan struct{})
    583 	mtx := make(chan struct{}, 1)
    584 	data := 0
    585 	go func() {
    586 		mtx <- struct{}{}
    587 		data = 42
    588 		<-mtx
    589 		done <- struct{}{}
    590 	}()
    591 	mtx <- struct{}{}
    592 	data = 43
    593 	<-mtx
    594 	<-done
    595 }
    596 
    597 func TestNoRaceSelectMutex(t *testing.T) {
    598 	done := make(chan struct{})
    599 	mtx := make(chan struct{}, 1)
    600 	aux := make(chan bool)
    601 	data := 0
    602 	go func() {
    603 		select {
    604 		case mtx <- struct{}{}:
    605 		case <-aux:
    606 		}
    607 		data = 42
    608 		select {
    609 		case <-mtx:
    610 		case <-aux:
    611 		}
    612 		done <- struct{}{}
    613 	}()
    614 	select {
    615 	case mtx <- struct{}{}:
    616 	case <-aux:
    617 	}
    618 	data = 43
    619 	select {
    620 	case <-mtx:
    621 	case <-aux:
    622 	}
    623 	<-done
    624 }
    625 
    626 func TestRaceChanSem(t *testing.T) {
    627 	done := make(chan struct{})
    628 	mtx := make(chan bool, 2)
    629 	data := 0
    630 	go func() {
    631 		mtx <- true
    632 		data = 42
    633 		<-mtx
    634 		done <- struct{}{}
    635 	}()
    636 	mtx <- true
    637 	data = 43
    638 	<-mtx
    639 	<-done
    640 }
    641 
    642 func TestNoRaceChanWaitGroup(t *testing.T) {
    643 	const N = 10
    644 	chanWg := make(chan bool, N/2)
    645 	data := make([]int, N)
    646 	for i := 0; i < N; i++ {
    647 		chanWg <- true
    648 		go func(i int) {
    649 			data[i] = 42
    650 			<-chanWg
    651 		}(i)
    652 	}
    653 	for i := 0; i < cap(chanWg); i++ {
    654 		chanWg <- true
    655 	}
    656 	for i := 0; i < N; i++ {
    657 		_ = data[i]
    658 	}
    659 }
    660