github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/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 TestNoRaceChanCloseLen(t *testing.T) { 581 c := make(chan int, 10) 582 r := make(chan int, 10) 583 go func() { 584 r <- len(c) 585 }() 586 go func() { 587 close(c) 588 r <- 0 589 }() 590 <-r 591 <-r 592 } 593 594 func TestNoRaceChanCloseCap(t *testing.T) { 595 c := make(chan int, 10) 596 r := make(chan int, 10) 597 go func() { 598 r <- cap(c) 599 }() 600 go func() { 601 close(c) 602 r <- 0 603 }() 604 <-r 605 <-r 606 } 607 608 func TestRaceChanCloseSend(t *testing.T) { 609 compl := make(chan bool, 1) 610 c := make(chan int, 10) 611 go func() { 612 close(c) 613 compl <- true 614 }() 615 c <- 0 616 <-compl 617 } 618 619 func TestNoRaceChanMutex(t *testing.T) { 620 done := make(chan struct{}) 621 mtx := make(chan struct{}, 1) 622 data := 0 623 _ = data 624 go func() { 625 mtx <- struct{}{} 626 data = 42 627 <-mtx 628 done <- struct{}{} 629 }() 630 mtx <- struct{}{} 631 data = 43 632 <-mtx 633 <-done 634 } 635 636 func TestNoRaceSelectMutex(t *testing.T) { 637 done := make(chan struct{}) 638 mtx := make(chan struct{}, 1) 639 aux := make(chan bool) 640 data := 0 641 _ = data 642 go func() { 643 select { 644 case mtx <- struct{}{}: 645 case <-aux: 646 } 647 data = 42 648 select { 649 case <-mtx: 650 case <-aux: 651 } 652 done <- struct{}{} 653 }() 654 select { 655 case mtx <- struct{}{}: 656 case <-aux: 657 } 658 data = 43 659 select { 660 case <-mtx: 661 case <-aux: 662 } 663 <-done 664 } 665 666 func TestRaceChanSem(t *testing.T) { 667 done := make(chan struct{}) 668 mtx := make(chan bool, 2) 669 data := 0 670 _ = data 671 go func() { 672 mtx <- true 673 data = 42 674 <-mtx 675 done <- struct{}{} 676 }() 677 mtx <- true 678 data = 43 679 <-mtx 680 <-done 681 } 682 683 func TestNoRaceChanWaitGroup(t *testing.T) { 684 const N = 10 685 chanWg := make(chan bool, N/2) 686 data := make([]int, N) 687 for i := 0; i < N; i++ { 688 chanWg <- true 689 go func(i int) { 690 data[i] = 42 691 <-chanWg 692 }(i) 693 } 694 for i := 0; i < cap(chanWg); i++ { 695 chanWg <- true 696 } 697 for i := 0; i < N; i++ { 698 _ = data[i] 699 } 700 } 701 702 // Test that sender synchronizes with receiver even if the sender was blocked. 703 func TestNoRaceBlockedSendSync(t *testing.T) { 704 c := make(chan *int, 1) 705 c <- nil 706 go func() { 707 i := 42 708 c <- &i 709 }() 710 // Give the sender time to actually block. 711 // This sleep is completely optional: race report must not be printed 712 // regardless of whether the sender actually blocks or not. 713 // It cannot lead to flakiness. 714 time.Sleep(10 * time.Millisecond) 715 <-c 716 p := <-c 717 if *p != 42 { 718 t.Fatal() 719 } 720 } 721 722 // The same as TestNoRaceBlockedSendSync above, but sender unblock happens in a select. 723 func TestNoRaceBlockedSelectSendSync(t *testing.T) { 724 c := make(chan *int, 1) 725 c <- nil 726 go func() { 727 i := 42 728 c <- &i 729 }() 730 time.Sleep(10 * time.Millisecond) 731 <-c 732 select { 733 case p := <-c: 734 if *p != 42 { 735 t.Fatal() 736 } 737 case <-make(chan int): 738 } 739 } 740 741 // Test that close synchronizes with a read from the empty closed channel. 742 // See https://golang.org/issue/36714. 743 func TestNoRaceCloseHappensBeforeRead(t *testing.T) { 744 for i := 0; i < 100; i++ { 745 var loc int 746 var write = make(chan struct{}) 747 var read = make(chan struct{}) 748 749 go func() { 750 select { 751 case <-write: 752 _ = loc 753 default: 754 } 755 close(read) 756 }() 757 758 go func() { 759 loc = 1 760 close(write) 761 }() 762 763 <-read 764 } 765 } 766 767 // Test that we call the proper race detector function when c.elemsize==0. 768 // See https://github.com/golang/go/issues/42598 769 func TestNoRaceElemetSize0(t *testing.T) { 770 var x, y int 771 var c = make(chan struct{}, 2) 772 c <- struct{}{} 773 c <- struct{}{} 774 go func() { 775 x += 1 776 <-c 777 }() 778 go func() { 779 y += 1 780 <-c 781 }() 782 time.Sleep(10 * time.Millisecond) 783 c <- struct{}{} 784 c <- struct{}{} 785 x += 1 786 y += 1 787 }