| | |
| | |
| | |
| |
|
| | package race_test |
| |
|
| | import ( |
| | "sync" |
| | "testing" |
| | "time" |
| | ) |
| |
|
| | func TestNoRaceCond(t *testing.T) { |
| | x := 0 |
| | _ = x |
| | condition := 0 |
| | var mu sync.Mutex |
| | cond := sync.NewCond(&mu) |
| | go func() { |
| | x = 1 |
| | mu.Lock() |
| | condition = 1 |
| | cond.Signal() |
| | mu.Unlock() |
| | }() |
| | mu.Lock() |
| | for condition != 1 { |
| | cond.Wait() |
| | } |
| | mu.Unlock() |
| | x = 2 |
| | } |
| |
|
| | func TestRaceCond(t *testing.T) { |
| | done := make(chan bool) |
| | var mu sync.Mutex |
| | cond := sync.NewCond(&mu) |
| | x := 0 |
| | _ = x |
| | condition := 0 |
| | go func() { |
| | time.Sleep(10 * time.Millisecond) |
| | x = 1 |
| | mu.Lock() |
| | condition = 1 |
| | cond.Signal() |
| | mu.Unlock() |
| | time.Sleep(10 * time.Millisecond) |
| | mu.Lock() |
| | x = 3 |
| | mu.Unlock() |
| | done <- true |
| | }() |
| | mu.Lock() |
| | for condition != 1 { |
| | cond.Wait() |
| | } |
| | mu.Unlock() |
| | x = 2 |
| | <-done |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func TestRaceAnnounceThreads(t *testing.T) { |
| | const N = 7 |
| | allDone := make(chan bool, N) |
| |
|
| | var x int |
| | _ = x |
| |
|
| | var f, g, h func() |
| | f = func() { |
| | x = 1 |
| | go g() |
| | go func() { |
| | x = 1 |
| | allDone <- true |
| | }() |
| | x = 2 |
| | allDone <- true |
| | } |
| |
|
| | g = func() { |
| | for i := 0; i < 2; i++ { |
| | go func() { |
| | x = 1 |
| | allDone <- true |
| | }() |
| | allDone <- true |
| | } |
| | } |
| |
|
| | h = func() { |
| | x = 1 |
| | x = 2 |
| | go f() |
| | allDone <- true |
| | } |
| |
|
| | go h() |
| |
|
| | for i := 0; i < N; i++ { |
| | <-allDone |
| | } |
| | } |
| |
|
| | func TestNoRaceAfterFunc1(t *testing.T) { |
| | i := 2 |
| | c := make(chan bool) |
| | var f func() |
| | f = func() { |
| | i-- |
| | if i >= 0 { |
| | time.AfterFunc(0, f) |
| | } else { |
| | c <- true |
| | } |
| | } |
| |
|
| | time.AfterFunc(0, f) |
| | <-c |
| | } |
| |
|
| | func TestNoRaceAfterFunc2(t *testing.T) { |
| | var x int |
| | _ = x |
| | timer := time.AfterFunc(10, func() { |
| | x = 1 |
| | }) |
| | defer timer.Stop() |
| | } |
| |
|
| | func TestNoRaceAfterFunc3(t *testing.T) { |
| | c := make(chan bool, 1) |
| | x := 0 |
| | _ = x |
| | time.AfterFunc(1e7, func() { |
| | x = 1 |
| | c <- true |
| | }) |
| | <-c |
| | } |
| |
|
| | func TestRaceAfterFunc3(t *testing.T) { |
| | c := make(chan bool, 2) |
| | x := 0 |
| | _ = x |
| | time.AfterFunc(1e7, func() { |
| | x = 1 |
| | c <- true |
| | }) |
| | time.AfterFunc(2e7, func() { |
| | x = 2 |
| | c <- true |
| | }) |
| | <-c |
| | <-c |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func TestRaceGoroutineCreationStack(t *testing.T) { |
| | var x int |
| | _ = x |
| | var ch = make(chan bool, 1) |
| |
|
| | f1 := func() { |
| | x = 1 |
| | ch <- true |
| | } |
| | f2 := func() { go f1() } |
| | f3 := func() { go f2() } |
| | f4 := func() { go f3() } |
| |
|
| | go f4() |
| | x = 2 |
| | <-ch |
| | } |
| |
|
| | |
| | |
| | |
| | func TestNoRaceNilMutexCrash(t *testing.T) { |
| | var mutex sync.Mutex |
| | panics := 0 |
| | defer func() { |
| | if x := recover(); x != nil { |
| | mutex.Lock() |
| | panics++ |
| | mutex.Unlock() |
| | } else { |
| | panic("no panic") |
| | } |
| | }() |
| | var othermutex *sync.RWMutex |
| | othermutex.RLock() |
| | } |
| |
|