github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/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 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 }() 315 c <- 1 316 compl <- true 317 }() 318 go func() { 319 time.Sleep(1e7) 320 close(c) 321 compl <- true 322 }() 323 <-compl 324 <-compl 325 } 326 327 func TestNoRaceProducerConsumerUnbuffered(t *testing.T) { 328 type Task struct { 329 f func() 330 done chan bool 331 } 332 333 queue := make(chan Task) 334 335 go func() { 336 t := <-queue 337 t.f() 338 t.done <- true 339 }() 340 341 doit := func(f func()) { 342 done := make(chan bool, 1) 343 queue <- Task{f, done} 344 <-done 345 } 346 347 x := 0 348 doit(func() { 349 x = 1 350 }) 351 _ = x 352 } 353 354 func TestRaceChanItselfSend(t *testing.T) { 355 compl := make(chan bool, 1) 356 c := make(chan int, 10) 357 go func() { 358 c <- 0 359 compl <- true 360 }() 361 c = make(chan int, 20) 362 <-compl 363 } 364 365 func TestRaceChanItselfRecv(t *testing.T) { 366 compl := make(chan bool, 1) 367 c := make(chan int, 10) 368 c <- 1 369 go func() { 370 <-c 371 compl <- true 372 }() 373 time.Sleep(1e7) 374 c = make(chan int, 20) 375 <-compl 376 } 377 378 func TestRaceChanItselfNil(t *testing.T) { 379 c := make(chan int, 10) 380 go func() { 381 c <- 0 382 }() 383 time.Sleep(1e7) 384 c = nil 385 _ = c 386 } 387 388 func TestRaceChanItselfClose(t *testing.T) { 389 compl := make(chan bool, 1) 390 c := make(chan int) 391 go func() { 392 close(c) 393 compl <- true 394 }() 395 c = make(chan int) 396 <-compl 397 } 398 399 func TestRaceChanItselfLen(t *testing.T) { 400 compl := make(chan bool, 1) 401 c := make(chan int) 402 go func() { 403 _ = len(c) 404 compl <- true 405 }() 406 c = make(chan int) 407 <-compl 408 } 409 410 func TestRaceChanItselfCap(t *testing.T) { 411 compl := make(chan bool, 1) 412 c := make(chan int) 413 go func() { 414 _ = cap(c) 415 compl <- true 416 }() 417 c = make(chan int) 418 <-compl 419 } 420 421 func TestRaceChanCloseLen(t *testing.T) { 422 v := 0 423 c := make(chan int, 10) 424 c <- 0 425 go func() { 426 v = 1 427 close(c) 428 }() 429 time.Sleep(1e7) 430 _ = len(c) 431 v = 2 432 } 433 434 func TestRaceChanSameCell(t *testing.T) { 435 c := make(chan int, 1) 436 v := 0 437 go func() { 438 v = 1 439 c <- 42 440 <-c 441 }() 442 time.Sleep(1e7) 443 c <- 43 444 <-c 445 _ = v 446 } 447 448 func TestRaceChanCloseSend(t *testing.T) { 449 compl := make(chan bool, 1) 450 c := make(chan int, 10) 451 go func() { 452 close(c) 453 compl <- true 454 }() 455 c <- 0 456 <-compl 457 }