github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/sync/once_test.go (about) 1 package sync_test 2 3 import ( 4 "sync" 5 "testing" 6 ) 7 8 // TestOnceUncontended tests Once on a single goroutine. 9 func TestOnceUncontended(t *testing.T) { 10 var once sync.Once 11 { 12 var ran bool 13 once.Do(func() { 14 ran = true 15 }) 16 if !ran { 17 t.Error("first call to Do did not run") 18 } 19 } 20 { 21 var ran bool 22 once.Do(func() { 23 ran = true 24 }) 25 if ran { 26 t.Error("second call to Do ran") 27 } 28 } 29 } 30 31 // TestOnceConcurrent tests multiple concurrent invocations of sync.Once. 32 func TestOnceConcurrent(t *testing.T) { 33 var once sync.Once 34 var mu sync.Mutex 35 mu.Lock() 36 var ran bool 37 var ranTwice bool 38 once.Do(func() { 39 ran = true 40 41 // Start a goroutine and (approximately) wait for it to enter the call to Do. 42 var startWait sync.Mutex 43 startWait.Lock() 44 go func() { 45 startWait.Unlock() 46 once.Do(func() { 47 ranTwice = true 48 }) 49 mu.Unlock() 50 }() 51 startWait.Lock() 52 }) 53 if !ran { 54 t.Error("first call to Do did not run") 55 } 56 57 // Wait for the goroutine to finish. 58 mu.Lock() 59 if ranTwice { 60 t.Error("second concurrent call to Once also ran") 61 } 62 }