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