github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/runtime/race/testdata/sync_test.go (about)

     1  // Copyright 2011 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 race_test
     6  
     7  import (
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestNoRaceCond(t *testing.T) {
    14  	x := 0
    15  	condition := 0
    16  	var mu sync.Mutex
    17  	cond := sync.NewCond(&mu)
    18  	go func() {
    19  		x = 1
    20  		mu.Lock()
    21  		condition = 1
    22  		cond.Signal()
    23  		mu.Unlock()
    24  	}()
    25  	mu.Lock()
    26  	for condition != 1 {
    27  		cond.Wait()
    28  	}
    29  	mu.Unlock()
    30  	x = 2
    31  }
    32  
    33  func TestRaceCond(t *testing.T) {
    34  	done := make(chan bool)
    35  	var mu sync.Mutex
    36  	cond := sync.NewCond(&mu)
    37  	x := 0
    38  	condition := 0
    39  	go func() {
    40  		time.Sleep(10 * time.Millisecond) // Enter cond.Wait loop
    41  		x = 1
    42  		mu.Lock()
    43  		condition = 1
    44  		cond.Signal()
    45  		mu.Unlock()
    46  		time.Sleep(10 * time.Millisecond) // Exit cond.Wait loop
    47  		mu.Lock()
    48  		x = 3
    49  		mu.Unlock()
    50  		done <- true
    51  	}()
    52  	mu.Lock()
    53  	for condition != 1 {
    54  		cond.Wait()
    55  	}
    56  	mu.Unlock()
    57  	x = 2
    58  	<-done
    59  }
    60  
    61  // We do not currently automatically
    62  // parse this test. It is intended that the creation
    63  // stack is observed manually not to contain
    64  // off-by-one errors
    65  func TestRaceAnnounceThreads(t *testing.T) {
    66  	const N = 7
    67  	allDone := make(chan bool, N)
    68  
    69  	var x int
    70  
    71  	var f, g, h func()
    72  	f = func() {
    73  		x = 1
    74  		go g()
    75  		go func() {
    76  			x = 1
    77  			allDone <- true
    78  		}()
    79  		x = 2
    80  		allDone <- true
    81  	}
    82  
    83  	g = func() {
    84  		for i := 0; i < 2; i++ {
    85  			go func() {
    86  				x = 1
    87  				allDone <- true
    88  			}()
    89  			allDone <- true
    90  		}
    91  	}
    92  
    93  	h = func() {
    94  		x = 1
    95  		x = 2
    96  		go f()
    97  		allDone <- true
    98  	}
    99  
   100  	go h()
   101  
   102  	for i := 0; i < N; i++ {
   103  		<-allDone
   104  	}
   105  }
   106  
   107  func TestNoRaceAfterFunc1(t *testing.T) {
   108  	i := 2
   109  	c := make(chan bool)
   110  	var f func()
   111  	f = func() {
   112  		i--
   113  		if i >= 0 {
   114  			time.AfterFunc(0, f)
   115  		} else {
   116  			c <- true
   117  		}
   118  	}
   119  
   120  	time.AfterFunc(0, f)
   121  	<-c
   122  }
   123  
   124  func TestNoRaceAfterFunc2(t *testing.T) {
   125  	var x int
   126  	timer := time.AfterFunc(10, func() {
   127  		x = 1
   128  	})
   129  	defer timer.Stop()
   130  	_ = x
   131  }
   132  
   133  func TestNoRaceAfterFunc3(t *testing.T) {
   134  	c := make(chan bool, 1)
   135  	x := 0
   136  	time.AfterFunc(1e7, func() {
   137  		x = 1
   138  		c <- true
   139  	})
   140  	<-c
   141  }
   142  
   143  func TestRaceAfterFunc3(t *testing.T) {
   144  	c := make(chan bool, 2)
   145  	x := 0
   146  	time.AfterFunc(1e7, func() {
   147  		x = 1
   148  		c <- true
   149  	})
   150  	time.AfterFunc(2e7, func() {
   151  		x = 2
   152  		c <- true
   153  	})
   154  	<-c
   155  	<-c
   156  }
   157  
   158  // This test's output is intended to be
   159  // observed manually. One should check
   160  // that goroutine creation stack is
   161  // comprehensible.
   162  func TestRaceGoroutineCreationStack(t *testing.T) {
   163  	var x int
   164  	var ch = make(chan bool, 1)
   165  
   166  	f1 := func() {
   167  		x = 1
   168  		ch <- true
   169  	}
   170  	f2 := func() { go f1() }
   171  	f3 := func() { go f2() }
   172  	f4 := func() { go f3() }
   173  
   174  	go f4()
   175  	x = 2
   176  	<-ch
   177  }
   178  
   179  // A nil pointer in a mutex method call should not
   180  // corrupt the race detector state.
   181  // Used to hang indefinitely.
   182  func TestNoRaceNilMutexCrash(t *testing.T) {
   183  	var mutex sync.Mutex
   184  	panics := 0
   185  	defer func() {
   186  		if x := recover(); x != nil {
   187  			mutex.Lock()
   188  			panics++
   189  			mutex.Unlock()
   190  		} else {
   191  			panic("no panic")
   192  		}
   193  	}()
   194  	var othermutex *sync.RWMutex
   195  	othermutex.RLock()
   196  }