Source file
src/runtime/chanbarrier_test.go
1
2
3
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 }
84
View as plain text