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