github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/chanbarrier_test.go (about) 1 // Copyright 2015 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 runtime_test 6 7 import ( 8 "runtime" 9 "sync" 10 "testing" 11 ) 12 13 type response struct { 14 } 15 16 type myError struct { 17 } 18 19 func (myError) Error() string { return "" } 20 21 func doRequest(useSelect bool) (*response, error) { 22 type async struct { 23 resp *response 24 err error 25 } 26 ch := make(chan *async, 0) 27 done := make(chan struct{}, 0) 28 29 if useSelect { 30 go func() { 31 select { 32 case ch <- &async{resp: nil, err: myError{}}: 33 case <-done: 34 } 35 }() 36 } else { 37 go func() { 38 ch <- &async{resp: nil, err: myError{}} 39 }() 40 } 41 42 r := <-ch 43 runtime.Gosched() 44 return r.resp, r.err 45 } 46 47 func TestChanSendSelectBarrier(t *testing.T) { 48 testChanSendBarrier(true) 49 } 50 51 func TestChanSendBarrier(t *testing.T) { 52 testChanSendBarrier(false) 53 } 54 55 func testChanSendBarrier(useSelect bool) { 56 var wg sync.WaitGroup 57 var globalMu sync.Mutex 58 outer := 100 59 inner := 100000 60 if testing.Short() || runtime.GOARCH == "wasm" { 61 outer = 10 62 inner = 1000 63 } 64 for i := 0; i < outer; i++ { 65 wg.Add(1) 66 go func() { 67 defer wg.Done() 68 var garbage []byte 69 for j := 0; j < inner; j++ { 70 _, err := doRequest(useSelect) 71 _, ok := err.(myError) 72 if !ok { 73 panic(1) 74 } 75 garbage = make([]byte, 1<<10) 76 } 77 globalMu.Lock() 78 global = garbage 79 globalMu.Unlock() 80 }() 81 } 82 wg.Wait() 83 }