Home | History | Annotate | Download | only in 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() {
     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