...
Run Format

Source file src/runtime/chanbarrier_test.go

Documentation: runtime

  // Copyright 2015 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package runtime_test
  
  import (
  	"runtime"
  	"sync"
  	"testing"
  )
  
  type response struct {
  }
  
  type myError struct {
  }
  
  func (myError) Error() string { return "" }
  
  func doRequest(useSelect bool) (*response, error) {
  	type async struct {
  		resp *response
  		err  error
  	}
  	ch := make(chan *async, 0)
  	done := make(chan struct{}, 0)
  
  	if useSelect {
  		go func() {
  			select {
  			case ch <- &async{resp: nil, err: myError{}}:
  			case <-done:
  			}
  		}()
  	} else {
  		go func() {
  			ch <- &async{resp: nil, err: myError{}}
  		}()
  	}
  
  	r := <-ch
  	runtime.Gosched()
  	return r.resp, r.err
  }
  
  func TestChanSendSelectBarrier(t *testing.T) {
  	testChanSendBarrier(true)
  }
  
  func TestChanSendBarrier(t *testing.T) {
  	testChanSendBarrier(false)
  }
  
  func testChanSendBarrier(useSelect bool) {
  	var wg sync.WaitGroup
  	var globalMu sync.Mutex
  	outer := 100
  	inner := 100000
  	if testing.Short() {
  		outer = 10
  		inner = 1000
  	}
  	for i := 0; i < outer; i++ {
  		wg.Add(1)
  		go func() {
  			defer wg.Done()
  			var garbage []byte
  			for j := 0; j < inner; j++ {
  				_, err := doRequest(useSelect)
  				_, ok := err.(myError)
  				if !ok {
  					panic(1)
  				}
  				garbage = make([]byte, 1<<10)
  			}
  			globalMu.Lock()
  			global = garbage
  			globalMu.Unlock()
  		}()
  	}
  	wg.Wait()
  }
  

View as plain text