github.com/searKing/golang/go@v1.2.117/sync/conditional_variable_test.go (about) 1 package sync_test 2 3 import ( 4 "context" 5 "sync" 6 "testing" 7 8 sync_ "github.com/searKing/golang/go/sync" 9 ) 10 11 func TestConditionVariable_Wait(t *testing.T) { 12 var m sync.Mutex 13 var c sync_.ConditionVariable 14 n := 2 15 running := make(chan bool, n) 16 awake := make(chan bool, n) 17 for i := 0; i < n; i++ { 18 go func() { 19 m.Lock() 20 running <- true 21 c.Wait(&m) 22 awake <- true 23 m.Unlock() 24 }() 25 } 26 for i := 0; i < n; i++ { 27 <-running // Wait for everyone to run. 28 } 29 for n > 0 { 30 select { 31 case <-awake: 32 t.Fatal("goroutine not asleep") 33 default: 34 } 35 m.Lock() 36 c.Signal() 37 m.Unlock() 38 <-awake // Will deadlock if no goroutine wakes up 39 select { 40 case <-awake: 41 t.Fatal("too many goroutines awake") 42 default: 43 } 44 n-- 45 } 46 c.Signal() 47 } 48 49 func TestConditionVariable_WaitPred(t *testing.T) { 50 var m sync.Mutex 51 var c sync_.ConditionVariable 52 n := 2 53 running := make(chan bool, n) 54 awake := make(chan bool, n) 55 56 ctx, cancel := context.WithCancel(context.Background()) 57 go func() { 58 m.Lock() 59 running <- true 60 c.WaitPred(&m, func() bool { 61 return ctx.Err() != nil 62 }) 63 awake <- true 64 m.Unlock() 65 }() 66 <-running // Wait for everyone to run. 67 68 select { 69 case <-awake: 70 t.Fatal("goroutine not asleep") 71 default: 72 } 73 m.Lock() 74 c.Signal() 75 m.Unlock() 76 cancel() 77 <-awake // Will deadlock if no goroutine wakes up 78 select { 79 case <-awake: 80 t.Fatal("too many goroutines awake") 81 default: 82 } 83 n-- 84 }