blob: 2332f097eb04dd008b4191b02e48014e85ba0a44 [file] [log] [blame]
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package race_test
import (
"runtime"
"testing"
"time"
)
func TestNoRaceChanSync(t *testing.T) {
v := 0
c := make(chan int)
go func() {
v = 1
c <- 0
}()
<-c
v = 2
}
func TestNoRaceChanSyncRev(t *testing.T) {
v := 0
c := make(chan int)
go func() {
c <- 0
v = 2
}()
v = 1
<-c
}
func TestNoRaceChanAsync(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
v = 1
c <- 0
}()
<-c
v = 2
}
func TestRaceChanAsyncRev(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
c <- 0
v = 1
}()
v = 2
<-c
}
func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
v = 1
close(c)
}()
func() {
defer func() {
recover()
v = 2
}()
<-c
}()
}
func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
v = 1
close(c)
}()
_, _ = <-c
v = 2
}
func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
v = 1
close(c)
}()
for _ = range c {
}
v = 2
}
func TestNoRaceChanSyncCloseRecv(t *testing.T) {
v := 0
c := make(chan int)
go func() {
v = 1
close(c)
}()
func() {
defer func() {
recover()
v = 2
}()
<-c
}()
}
func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
v := 0
c := make(chan int)
go func() {
v = 1
close(c)
}()
_, _ = <-c
v = 2
}
func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
v := 0
c := make(chan int)
go func() {
v = 1
close(c)
}()
for _ = range c {
}
v = 2
}
func TestRaceChanSyncCloseSend(t *testing.T) {
v := 0
c := make(chan int)
go func() {
v = 1
close(c)
}()
func() {
defer func() {
recover()
}()
c <- 0
}()
v = 2
}
func TestRaceChanAsyncCloseSend(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
v = 1
close(c)
}()
func() {
defer func() {
recover()
}()
for {
c <- 0
}
}()
v = 2
}
func TestRaceChanCloseClose(t *testing.T) {
compl := make(chan bool, 2)
v1 := 0
v2 := 0
c := make(chan int)
go func() {
defer func() {
if recover() != nil {
v2 = 2
}
compl <- true
}()
v1 = 1
close(c)
}()
go func() {
defer func() {
if recover() != nil {
v1 = 2
}
compl <- true
}()
v2 = 1
close(c)
}()
<-compl
<-compl
}
func TestRaceChanSendLen(t *testing.T) {
v := 0
c := make(chan int, 10)
go func() {
v = 1
c <- 1
}()
for len(c) == 0 {
runtime.Gosched()
}
v = 2
}
func TestRaceChanRecvLen(t *testing.T) {
v := 0
c := make(chan int, 10)
c <- 1
go func() {
v = 1
<-c
}()
for len(c) != 0 {
runtime.Gosched()
}
v = 2
}
func TestRaceChanSendSend(t *testing.T) {
compl := make(chan bool, 2)
v1 := 0
v2 := 0
c := make(chan int, 1)
go func() {
v1 = 1
select {
case c <- 1:
default:
v2 = 2
}
compl <- true
}()
go func() {
v2 = 1
select {
case c <- 1:
default:
v1 = 2
}
compl <- true
}()
<-compl
<-compl
}
func TestNoRaceChanPtr(t *testing.T) {
type msg struct {
x int
}
c := make(chan *msg)
go func() {
c <- &msg{1}
}()
m := <-c
m.x = 2
}
func TestRaceChanWrongSend(t *testing.T) {
v1 := 0
v2 := 0
c := make(chan int, 2)
go func() {
v1 = 1
c <- 1
}()
go func() {
v2 = 2
c <- 2
}()
time.Sleep(1e7)
if <-c == 1 {
v2 = 3
} else {
v1 = 3
}
}
func TestRaceChanWrongClose(t *testing.T) {
v1 := 0
v2 := 0
c := make(chan int, 1)
go func() {
defer func() {
recover()
}()
v1 = 1
c <- 1
}()
go func() {
time.Sleep(1e7)
v2 = 2
close(c)
}()
time.Sleep(2e7)
if _, who := <-c; who {
v2 = 2
} else {
v1 = 2
}
}
func TestRaceChanSendClose(t *testing.T) {
compl := make(chan bool, 2)
c := make(chan int, 1)
go func() {
defer func() {
recover()
}()
c <- 1
compl <- true
}()
go func() {
time.Sleep(1e7)
close(c)
compl <- true
}()
<-compl
<-compl
}
func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
type Task struct {
f func()
done chan bool
}
queue := make(chan Task)
go func() {
t := <-queue
t.f()
t.done <- true
}()
doit := func(f func()) {
done := make(chan bool, 1)
queue <- Task{f, done}
<-done
}
x := 0
doit(func() {
x = 1
})
_ = x
}
func TestRaceChanItselfSend(t *testing.T) {
compl := make(chan bool, 1)
c := make(chan int, 10)
go func() {
c <- 0
compl <- true
}()
c = make(chan int, 20)
<-compl
}
func TestRaceChanItselfRecv(t *testing.T) {
compl := make(chan bool, 1)
c := make(chan int, 10)
c <- 1
go func() {
<-c
compl <- true
}()
time.Sleep(1e7)
c = make(chan int, 20)
<-compl
}
func TestRaceChanItselfNil(t *testing.T) {
c := make(chan int, 10)
go func() {
c <- 0
}()
time.Sleep(1e7)
c = nil
_ = c
}
func TestRaceChanItselfClose(t *testing.T) {
compl := make(chan bool, 1)
c := make(chan int)
go func() {
close(c)
compl <- true
}()
c = make(chan int)
<-compl
}
func TestRaceChanItselfLen(t *testing.T) {
compl := make(chan bool, 1)
c := make(chan int)
go func() {
_ = len(c)
compl <- true
}()
c = make(chan int)
<-compl
}
func TestRaceChanItselfCap(t *testing.T) {
compl := make(chan bool, 1)
c := make(chan int)
go func() {
_ = cap(c)
compl <- true
}()
c = make(chan int)
<-compl
}
func TestRaceChanCloseLen(t *testing.T) {
v := 0
c := make(chan int, 10)
c <- 0
go func() {
v = 1
close(c)
}()
time.Sleep(1e7)
_ = len(c)
v = 2
}
func TestRaceChanSameCell(t *testing.T) {
c := make(chan int, 1)
v := 0
go func() {
v = 1
c <- 42
<-c
}()
time.Sleep(1e7)
c <- 43
<-c
_ = v
}
func TestRaceChanCloseSend(t *testing.T) {
compl := make(chan bool, 1)
c := make(chan int, 10)
go func() {
close(c)
compl <- true
}()
c <- 0
<-compl
}