...

Source file src/runtime/chanbarrier_test.go

Documentation: runtime

		 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  }
		84  

View as plain text