github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/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 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 done := make(chan bool) 289 go func() { 290 defer func() { 291 recover() 292 }() 293 v1 = 1 294 c <- 1 295 done <- true 296 }() 297 go func() { 298 time.Sleep(1e7) 299 v2 = 2 300 close(c) 301 done <- true 302 }() 303 time.Sleep(2e7) 304 if _, who := <-c; who { 305 v2 = 2 306 } else { 307 v1 = 2 308 } 309 <-done 310 <-done 311 } 312 313 func TestRaceChanSendClose(t *testing.T) { 314 compl := make(chan bool, 2) 315 c := make(chan int, 1) 316 go func() { 317 defer func() { 318 recover() 319 compl <- true 320 }() 321 c <- 1 322 }() 323 go func() { 324 time.Sleep(10 * time.Millisecond) 325 close(c) 326 compl <- true 327 }() 328 <-compl 329 <-compl 330 } 331 332 func TestRaceChanSendSelectClose(t *testing.T) { 333 compl := make(chan bool, 2) 334 c := make(chan int, 1) 335 c1 := make(chan int) 336 go func() { 337 defer func() { 338 recover() 339 compl <- true 340 }() 341 time.Sleep(10 * time.Millisecond) 342 select { 343 case c <- 1: 344 case <-c1: 345 } 346 }() 347 go func() { 348 close(c) 349 compl <- true 350 }() 351 <-compl 352 <-compl 353 } 354 355 func TestRaceSelectReadWriteAsync(t *testing.T) { 356 done := make(chan bool) 357 x := 0 358 c1 := make(chan int, 10) 359 c2 := make(chan int, 10) 360 c3 := make(chan int) 361 c2 <- 1 362 go func() { 363 select { 364 case c1 <- x: // read of x races with... 365 case c3 <- 1: 366 } 367 done <- true 368 }() 369 select { 370 case x = <-c2: // ... write to x here 371 case c3 <- 1: 372 } 373 <-done 374 } 375 376 func TestRaceSelectReadWriteSync(t *testing.T) { 377 done := make(chan bool) 378 x := 0 379 c1 := make(chan int) 380 c2 := make(chan int) 381 c3 := make(chan int) 382 // make c1 and c2 ready for communication 383 go func() { 384 <-c1 385 }() 386 go func() { 387 c2 <- 1 388 }() 389 go func() { 390 select { 391 case c1 <- x: // read of x races with... 392 case c3 <- 1: 393 } 394 done <- true 395 }() 396 select { 397 case x = <-c2: // ... write to x here 398 case c3 <- 1: 399 } 400 <-done 401 } 402 403 func TestNoRaceSelectReadWriteAsync(t *testing.T) { 404 done := make(chan bool) 405 x := 0 406 c1 := make(chan int) 407 c2 := make(chan int) 408 go func() { 409 select { 410 case c1 <- x: // read of x does not race with... 411 case c2 <- 1: 412 } 413 done <- true 414 }() 415 select { 416 case x = <-c1: // ... write to x here 417 case c2 <- 1: 418 } 419 <-done 420 } 421 422 func TestRaceChanReadWriteAsync(t *testing.T) { 423 done := make(chan bool) 424 c1 := make(chan int, 10) 425 c2 := make(chan int, 10) 426 c2 <- 10 427 x := 0 428 go func() { 429 c1 <- x // read of x races with... 430 done <- true 431 }() 432 x = <-c2 // ... write to x here 433 <-done 434 } 435 436 func TestRaceChanReadWriteSync(t *testing.T) { 437 done := make(chan bool) 438 c1 := make(chan int) 439 c2 := make(chan int) 440 // make c1 and c2 ready for communication 441 go func() { 442 <-c1 443 }() 444 go func() { 445 c2 <- 10 446 }() 447 x := 0 448 go func() { 449 c1 <- x // read of x races with... 450 done <- true 451 }() 452 x = <-c2 // ... write to x here 453 <-done 454 } 455 456 func TestNoRaceChanReadWriteAsync(t *testing.T) { 457 done := make(chan bool) 458 c1 := make(chan int, 10) 459 x := 0 460 go func() { 461 c1 <- x // read of x does not race with... 462 done <- true 463 }() 464 x = <-c1 // ... write to x here 465 <-done 466 } 467 468 func TestNoRaceProducerConsumerUnbuffered(t *testing.T) { 469 type Task struct { 470 f func() 471 done chan bool 472 } 473 474 queue := make(chan Task) 475 476 go func() { 477 t := <-queue 478 t.f() 479 t.done <- true 480 }() 481 482 doit := func(f func()) { 483 done := make(chan bool, 1) 484 queue <- Task{f, done} 485 <-done 486 } 487 488 x := 0 489 doit(func() { 490 x = 1 491 }) 492 _ = x 493 } 494 495 func TestRaceChanItselfSend(t *testing.T) { 496 compl := make(chan bool, 1) 497 c := make(chan int, 10) 498 go func() { 499 c <- 0 500 compl <- true 501 }() 502 c = make(chan int, 20) 503 <-compl 504 } 505 506 func TestRaceChanItselfRecv(t *testing.T) { 507 compl := make(chan bool, 1) 508 c := make(chan int, 10) 509 c <- 1 510 go func() { 511 <-c 512 compl <- true 513 }() 514 time.Sleep(1e7) 515 c = make(chan int, 20) 516 <-compl 517 } 518 519 func TestRaceChanItselfNil(t *testing.T) { 520 c := make(chan int, 10) 521 go func() { 522 c <- 0 523 }() 524 time.Sleep(1e7) 525 c = nil 526 _ = c 527 } 528 529 func TestRaceChanItselfClose(t *testing.T) { 530 compl := make(chan bool, 1) 531 c := make(chan int) 532 go func() { 533 close(c) 534 compl <- true 535 }() 536 c = make(chan int) 537 <-compl 538 } 539 540 func TestRaceChanItselfLen(t *testing.T) { 541 compl := make(chan bool, 1) 542 c := make(chan int) 543 go func() { 544 _ = len(c) 545 compl <- true 546 }() 547 c = make(chan int) 548 <-compl 549 } 550 551 func TestRaceChanItselfCap(t *testing.T) { 552 compl := make(chan bool, 1) 553 c := make(chan int) 554 go func() { 555 _ = cap(c) 556 compl <- true 557 }() 558 c = make(chan int) 559 <-compl 560 } 561 562 func TestRaceChanCloseLen(t *testing.T) { 563 v := 0 564 c := make(chan int, 10) 565 c <- 0 566 go func() { 567 v = 1 568 close(c) 569 }() 570 time.Sleep(1e7) 571 _ = len(c) 572 v = 2 573 } 574 575 func TestRaceChanCloseSend(t *testing.T) { 576 compl := make(chan bool, 1) 577 c := make(chan int, 10) 578 go func() { 579 close(c) 580 compl <- true 581 }() 582 c <- 0 583 <-compl 584 } 585 586 func TestNoRaceChanMutex(t *testing.T) { 587 done := make(chan struct{}) 588 mtx := make(chan struct{}, 1) 589 data := 0 590 go func() { 591 mtx <- struct{}{} 592 data = 42 593 <-mtx 594 done <- struct{}{} 595 }() 596 mtx <- struct{}{} 597 data = 43 598 <-mtx 599 <-done 600 } 601 602 func TestNoRaceSelectMutex(t *testing.T) { 603 done := make(chan struct{}) 604 mtx := make(chan struct{}, 1) 605 aux := make(chan bool) 606 data := 0 607 go func() { 608 select { 609 case mtx <- struct{}{}: 610 case <-aux: 611 } 612 data = 42 613 select { 614 case <-mtx: 615 case <-aux: 616 } 617 done <- struct{}{} 618 }() 619 select { 620 case mtx <- struct{}{}: 621 case <-aux: 622 } 623 data = 43 624 select { 625 case <-mtx: 626 case <-aux: 627 } 628 <-done 629 } 630 631 func TestRaceChanSem(t *testing.T) { 632 done := make(chan struct{}) 633 mtx := make(chan bool, 2) 634 data := 0 635 go func() { 636 mtx <- true 637 data = 42 638 <-mtx 639 done <- struct{}{} 640 }() 641 mtx <- true 642 data = 43 643 <-mtx 644 <-done 645 } 646 647 func TestNoRaceChanWaitGroup(t *testing.T) { 648 const N = 10 649 chanWg := make(chan bool, N/2) 650 data := make([]int, N) 651 for i := 0; i < N; i++ { 652 chanWg <- true 653 go func(i int) { 654 data[i] = 42 655 <-chanWg 656 }(i) 657 } 658 for i := 0; i < cap(chanWg); i++ { 659 chanWg <- true 660 } 661 for i := 0; i < N; i++ { 662 _ = data[i] 663 } 664 } 665 666 // Test that sender synchronizes with receiver even if the sender was blocked. 667 func TestNoRaceBlockedSendSync(t *testing.T) { 668 c := make(chan *int, 1) 669 c <- nil 670 go func() { 671 i := 42 672 c <- &i 673 }() 674 // Give the sender time to actually block. 675 // This sleep is completely optional: race report must not be printed 676 // regardless of whether the sender actually blocks or not. 677 // It cannot lead to flakiness. 678 time.Sleep(10 * time.Millisecond) 679 <-c 680 p := <-c 681 if *p != 42 { 682 t.Fatal() 683 } 684 } 685 686 // The same as TestNoRaceBlockedSendSync above, but sender unblock happens in a select. 687 func TestNoRaceBlockedSelectSendSync(t *testing.T) { 688 c := make(chan *int, 1) 689 c <- nil 690 go func() { 691 i := 42 692 c <- &i 693 }() 694 time.Sleep(10 * time.Millisecond) 695 <-c 696 select { 697 case p := <-c: 698 if *p != 42 { 699 t.Fatal() 700 } 701 case <-make(chan int): 702 } 703 }