github.com/aloncn/graphics-go@v0.0.1/src/runtime/race/testdata/chan_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  	"runtime"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestNoRaceChanSync(t *testing.T) {
    14  	v := 0
    15  	c := make(chan int)
    16  	go func() {
    17  		v = 1
    18  		c <- 0
    19  	}()
    20  	<-c
    21  	v = 2
    22  }
    23  
    24  func TestNoRaceChanSyncRev(t *testing.T) {
    25  	v := 0
    26  	c := make(chan int)
    27  	go func() {
    28  		c <- 0
    29  		v = 2
    30  	}()
    31  	v = 1
    32  	<-c
    33  }
    34  
    35  func TestNoRaceChanAsync(t *testing.T) {
    36  	v := 0
    37  	c := make(chan int, 10)
    38  	go func() {
    39  		v = 1
    40  		c <- 0
    41  	}()
    42  	<-c
    43  	v = 2
    44  }
    45  
    46  func TestRaceChanAsyncRev(t *testing.T) {
    47  	v := 0
    48  	c := make(chan int, 10)
    49  	go func() {
    50  		c <- 0
    51  		v = 1
    52  	}()
    53  	v = 2
    54  	<-c
    55  }
    56  
    57  func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
    58  	v := 0
    59  	c := make(chan int, 10)
    60  	go func() {
    61  		v = 1
    62  		close(c)
    63  	}()
    64  	func() {
    65  		defer func() {
    66  			recover()
    67  			v = 2
    68  		}()
    69  		<-c
    70  	}()
    71  }
    72  
    73  func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
    74  	v := 0
    75  	c := make(chan int, 10)
    76  	go func() {
    77  		v = 1
    78  		close(c)
    79  	}()
    80  	_, _ = <-c
    81  	v = 2
    82  }
    83  
    84  func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
    85  	v := 0
    86  	c := make(chan int, 10)
    87  	go func() {
    88  		v = 1
    89  		close(c)
    90  	}()
    91  	for range c {
    92  	}
    93  	v = 2
    94  }
    95  
    96  func TestNoRaceChanSyncCloseRecv(t *testing.T) {
    97  	v := 0
    98  	c := make(chan int)
    99  	go func() {
   100  		v = 1
   101  		close(c)
   102  	}()
   103  	func() {
   104  		defer func() {
   105  			recover()
   106  			v = 2
   107  		}()
   108  		<-c
   109  	}()
   110  }
   111  
   112  func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
   113  	v := 0
   114  	c := make(chan int)
   115  	go func() {
   116  		v = 1
   117  		close(c)
   118  	}()
   119  	_, _ = <-c
   120  	v = 2
   121  }
   122  
   123  func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
   124  	v := 0
   125  	c := make(chan int)
   126  	go func() {
   127  		v = 1
   128  		close(c)
   129  	}()
   130  	for range c {
   131  	}
   132  	v = 2
   133  }
   134  
   135  func TestRaceChanSyncCloseSend(t *testing.T) {
   136  	v := 0
   137  	c := make(chan int)
   138  	go func() {
   139  		v = 1
   140  		close(c)
   141  	}()
   142  	func() {
   143  		defer func() {
   144  			recover()
   145  		}()
   146  		c <- 0
   147  	}()
   148  	v = 2
   149  }
   150  
   151  func TestRaceChanAsyncCloseSend(t *testing.T) {
   152  	v := 0
   153  	c := make(chan int, 10)
   154  	go func() {
   155  		v = 1
   156  		close(c)
   157  	}()
   158  	func() {
   159  		defer func() {
   160  			recover()
   161  		}()
   162  		for {
   163  			c <- 0
   164  		}
   165  	}()
   166  	v = 2
   167  }
   168  
   169  func TestRaceChanCloseClose(t *testing.T) {
   170  	compl := make(chan bool, 2)
   171  	v1 := 0
   172  	v2 := 0
   173  	c := make(chan int)
   174  	go func() {
   175  		defer func() {
   176  			if recover() != nil {
   177  				v2 = 2
   178  			}
   179  			compl <- true
   180  		}()
   181  		v1 = 1
   182  		close(c)
   183  	}()
   184  	go func() {
   185  		defer func() {
   186  			if recover() != nil {
   187  				v1 = 2
   188  			}
   189  			compl <- true
   190  		}()
   191  		v2 = 1
   192  		close(c)
   193  	}()
   194  	<-compl
   195  	<-compl
   196  }
   197  
   198  func TestRaceChanSendLen(t *testing.T) {
   199  	v := 0
   200  	c := make(chan int, 10)
   201  	go func() {
   202  		v = 1
   203  		c <- 1
   204  	}()
   205  	for len(c) == 0 {
   206  		runtime.Gosched()
   207  	}
   208  	v = 2
   209  }
   210  
   211  func TestRaceChanRecvLen(t *testing.T) {
   212  	v := 0
   213  	c := make(chan int, 10)
   214  	c <- 1
   215  	go func() {
   216  		v = 1
   217  		<-c
   218  	}()
   219  	for len(c) != 0 {
   220  		runtime.Gosched()
   221  	}
   222  	v = 2
   223  }
   224  
   225  func TestRaceChanSendSend(t *testing.T) {
   226  	compl := make(chan bool, 2)
   227  	v1 := 0
   228  	v2 := 0
   229  	c := make(chan int, 1)
   230  	go func() {
   231  		v1 = 1
   232  		select {
   233  		case c <- 1:
   234  		default:
   235  			v2 = 2
   236  		}
   237  		compl <- true
   238  	}()
   239  	go func() {
   240  		v2 = 1
   241  		select {
   242  		case c <- 1:
   243  		default:
   244  			v1 = 2
   245  		}
   246  		compl <- true
   247  	}()
   248  	<-compl
   249  	<-compl
   250  }
   251  
   252  func TestNoRaceChanPtr(t *testing.T) {
   253  	type msg struct {
   254  		x int
   255  	}
   256  	c := make(chan *msg)
   257  	go func() {
   258  		c <- &msg{1}
   259  	}()
   260  	m := <-c
   261  	m.x = 2
   262  }
   263  
   264  func TestRaceChanWrongSend(t *testing.T) {
   265  	v1 := 0
   266  	v2 := 0
   267  	c := make(chan int, 2)
   268  	go func() {
   269  		v1 = 1
   270  		c <- 1
   271  	}()
   272  	go func() {
   273  		v2 = 2
   274  		c <- 2
   275  	}()
   276  	time.Sleep(1e7)
   277  	if <-c == 1 {
   278  		v2 = 3
   279  	} else {
   280  		v1 = 3
   281  	}
   282  }
   283  
   284  func TestRaceChanWrongClose(t *testing.T) {
   285  	v1 := 0
   286  	v2 := 0
   287  	c := make(chan int, 1)
   288  	go func() {
   289  		defer func() {
   290  			recover()
   291  		}()
   292  		v1 = 1
   293  		c <- 1
   294  	}()
   295  	go func() {
   296  		time.Sleep(1e7)
   297  		v2 = 2
   298  		close(c)
   299  	}()
   300  	time.Sleep(2e7)
   301  	if _, who := <-c; who {
   302  		v2 = 2
   303  	} else {
   304  		v1 = 2
   305  	}
   306  }
   307  
   308  func TestRaceChanSendClose(t *testing.T) {
   309  	compl := make(chan bool, 2)
   310  	c := make(chan int, 1)
   311  	go func() {
   312  		defer func() {
   313  			recover()
   314  			compl <- true
   315  		}()
   316  		c <- 1
   317  	}()
   318  	go func() {
   319  		time.Sleep(10 * time.Millisecond)
   320  		close(c)
   321  		compl <- true
   322  	}()
   323  	<-compl
   324  	<-compl
   325  }
   326  
   327  func TestRaceChanSendSelectClose(t *testing.T) {
   328  	compl := make(chan bool, 2)
   329  	c := make(chan int, 1)
   330  	c1 := make(chan int)
   331  	go func() {
   332  		defer func() {
   333  			recover()
   334  			compl <- true
   335  		}()
   336  		time.Sleep(10 * time.Millisecond)
   337  		select {
   338  		case c <- 1:
   339  		case <-c1:
   340  		}
   341  	}()
   342  	go func() {
   343  		close(c)
   344  		compl <- true
   345  	}()
   346  	<-compl
   347  	<-compl
   348  }
   349  
   350  func TestRaceSelectReadWriteAsync(t *testing.T) {
   351  	done := make(chan bool)
   352  	x := 0
   353  	c1 := make(chan int, 10)
   354  	c2 := make(chan int, 10)
   355  	c3 := make(chan int)
   356  	c2 <- 1
   357  	go func() {
   358  		select {
   359  		case c1 <- x: // read of x races with...
   360  		case c3 <- 1:
   361  		}
   362  		done <- true
   363  	}()
   364  	select {
   365  	case x = <-c2: // ... write to x here
   366  	case c3 <- 1:
   367  	}
   368  	<-done
   369  }
   370  
   371  func TestRaceSelectReadWriteSync(t *testing.T) {
   372  	done := make(chan bool)
   373  	x := 0
   374  	c1 := make(chan int)
   375  	c2 := make(chan int)
   376  	c3 := make(chan int)
   377  	// make c1 and c2 ready for communication
   378  	go func() {
   379  		<-c1
   380  	}()
   381  	go func() {
   382  		c2 <- 1
   383  	}()
   384  	go func() {
   385  		select {
   386  		case c1 <- x: // read of x races with...
   387  		case c3 <- 1:
   388  		}
   389  		done <- true
   390  	}()
   391  	select {
   392  	case x = <-c2: // ... write to x here
   393  	case c3 <- 1:
   394  	}
   395  	<-done
   396  }
   397  
   398  func TestNoRaceSelectReadWriteAsync(t *testing.T) {
   399  	done := make(chan bool)
   400  	x := 0
   401  	c1 := make(chan int)
   402  	c2 := make(chan int)
   403  	go func() {
   404  		select {
   405  		case c1 <- x: // read of x does not race with...
   406  		case c2 <- 1:
   407  		}
   408  		done <- true
   409  	}()
   410  	select {
   411  	case x = <-c1: // ... write to x here
   412  	case c2 <- 1:
   413  	}
   414  	<-done
   415  }
   416  
   417  func TestRaceChanReadWriteAsync(t *testing.T) {
   418  	done := make(chan bool)
   419  	c1 := make(chan int, 10)
   420  	c2 := make(chan int, 10)
   421  	c2 <- 10
   422  	x := 0
   423  	go func() {
   424  		c1 <- x // read of x races with...
   425  		done <- true
   426  	}()
   427  	x = <-c2 // ... write to x here
   428  	<-done
   429  }
   430  
   431  func TestRaceChanReadWriteSync(t *testing.T) {
   432  	done := make(chan bool)
   433  	c1 := make(chan int)
   434  	c2 := make(chan int)
   435  	// make c1 and c2 ready for communication
   436  	go func() {
   437  		<-c1
   438  	}()
   439  	go func() {
   440  		c2 <- 10
   441  	}()
   442  	x := 0
   443  	go func() {
   444  		c1 <- x // read of x races with...
   445  		done <- true
   446  	}()
   447  	x = <-c2 // ... write to x here
   448  	<-done
   449  }
   450  
   451  func TestNoRaceChanReadWriteAsync(t *testing.T) {
   452  	done := make(chan bool)
   453  	c1 := make(chan int, 10)
   454  	x := 0
   455  	go func() {
   456  		c1 <- x // read of x does not race with...
   457  		done <- true
   458  	}()
   459  	x = <-c1 // ... write to x here
   460  	<-done
   461  }
   462  
   463  func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
   464  	type Task struct {
   465  		f    func()
   466  		done chan bool
   467  	}
   468  
   469  	queue := make(chan Task)
   470  
   471  	go func() {
   472  		t := <-queue
   473  		t.f()
   474  		t.done <- true
   475  	}()
   476  
   477  	doit := func(f func()) {
   478  		done := make(chan bool, 1)
   479  		queue <- Task{f, done}
   480  		<-done
   481  	}
   482  
   483  	x := 0
   484  	doit(func() {
   485  		x = 1
   486  	})
   487  	_ = x
   488  }
   489  
   490  func TestRaceChanItselfSend(t *testing.T) {
   491  	compl := make(chan bool, 1)
   492  	c := make(chan int, 10)
   493  	go func() {
   494  		c <- 0
   495  		compl <- true
   496  	}()
   497  	c = make(chan int, 20)
   498  	<-compl
   499  }
   500  
   501  func TestRaceChanItselfRecv(t *testing.T) {
   502  	compl := make(chan bool, 1)
   503  	c := make(chan int, 10)
   504  	c <- 1
   505  	go func() {
   506  		<-c
   507  		compl <- true
   508  	}()
   509  	time.Sleep(1e7)
   510  	c = make(chan int, 20)
   511  	<-compl
   512  }
   513  
   514  func TestRaceChanItselfNil(t *testing.T) {
   515  	c := make(chan int, 10)
   516  	go func() {
   517  		c <- 0
   518  	}()
   519  	time.Sleep(1e7)
   520  	c = nil
   521  	_ = c
   522  }
   523  
   524  func TestRaceChanItselfClose(t *testing.T) {
   525  	compl := make(chan bool, 1)
   526  	c := make(chan int)
   527  	go func() {
   528  		close(c)
   529  		compl <- true
   530  	}()
   531  	c = make(chan int)
   532  	<-compl
   533  }
   534  
   535  func TestRaceChanItselfLen(t *testing.T) {
   536  	compl := make(chan bool, 1)
   537  	c := make(chan int)
   538  	go func() {
   539  		_ = len(c)
   540  		compl <- true
   541  	}()
   542  	c = make(chan int)
   543  	<-compl
   544  }
   545  
   546  func TestRaceChanItselfCap(t *testing.T) {
   547  	compl := make(chan bool, 1)
   548  	c := make(chan int)
   549  	go func() {
   550  		_ = cap(c)
   551  		compl <- true
   552  	}()
   553  	c = make(chan int)
   554  	<-compl
   555  }
   556  
   557  func TestRaceChanCloseLen(t *testing.T) {
   558  	v := 0
   559  	c := make(chan int, 10)
   560  	c <- 0
   561  	go func() {
   562  		v = 1
   563  		close(c)
   564  	}()
   565  	time.Sleep(1e7)
   566  	_ = len(c)
   567  	v = 2
   568  }
   569  
   570  func TestRaceChanCloseSend(t *testing.T) {
   571  	compl := make(chan bool, 1)
   572  	c := make(chan int, 10)
   573  	go func() {
   574  		close(c)
   575  		compl <- true
   576  	}()
   577  	c <- 0
   578  	<-compl
   579  }
   580  
   581  func TestNoRaceChanMutex(t *testing.T) {
   582  	done := make(chan struct{})
   583  	mtx := make(chan struct{}, 1)
   584  	data := 0
   585  	go func() {
   586  		mtx <- struct{}{}
   587  		data = 42
   588  		<-mtx
   589  		done <- struct{}{}
   590  	}()
   591  	mtx <- struct{}{}
   592  	data = 43
   593  	<-mtx
   594  	<-done
   595  }
   596  
   597  func TestNoRaceSelectMutex(t *testing.T) {
   598  	done := make(chan struct{})
   599  	mtx := make(chan struct{}, 1)
   600  	aux := make(chan bool)
   601  	data := 0
   602  	go func() {
   603  		select {
   604  		case mtx <- struct{}{}:
   605  		case <-aux:
   606  		}
   607  		data = 42
   608  		select {
   609  		case <-mtx:
   610  		case <-aux:
   611  		}
   612  		done <- struct{}{}
   613  	}()
   614  	select {
   615  	case mtx <- struct{}{}:
   616  	case <-aux:
   617  	}
   618  	data = 43
   619  	select {
   620  	case <-mtx:
   621  	case <-aux:
   622  	}
   623  	<-done
   624  }
   625  
   626  func TestRaceChanSem(t *testing.T) {
   627  	done := make(chan struct{})
   628  	mtx := make(chan bool, 2)
   629  	data := 0
   630  	go func() {
   631  		mtx <- true
   632  		data = 42
   633  		<-mtx
   634  		done <- struct{}{}
   635  	}()
   636  	mtx <- true
   637  	data = 43
   638  	<-mtx
   639  	<-done
   640  }
   641  
   642  func TestNoRaceChanWaitGroup(t *testing.T) {
   643  	const N = 10
   644  	chanWg := make(chan bool, N/2)
   645  	data := make([]int, N)
   646  	for i := 0; i < N; i++ {
   647  		chanWg <- true
   648  		go func(i int) {
   649  			data[i] = 42
   650  			<-chanWg
   651  		}(i)
   652  	}
   653  	for i := 0; i < cap(chanWg); i++ {
   654  		chanWg <- true
   655  	}
   656  	for i := 0; i < N; i++ {
   657  		_ = data[i]
   658  	}
   659  }
   660  
   661  // Test that sender synchronizes with receiver even if the sender was blocked.
   662  func TestNoRaceBlockedSendSync(t *testing.T) {
   663  	c := make(chan *int, 1)
   664  	c <- nil
   665  	go func() {
   666  		i := 42
   667  		c <- &i
   668  	}()
   669  	// Give the sender time to actually block.
   670  	// This sleep is completely optional: race report must not be printed
   671  	// regardless of whether the sender actually blocks or not.
   672  	// It cannot lead to flakiness.
   673  	time.Sleep(10 * time.Millisecond)
   674  	<-c
   675  	p := <-c
   676  	if *p != 42 {
   677  		t.Fatal()
   678  	}
   679  }
   680  
   681  // The same as TestNoRaceBlockedSendSync above, but sender unblock happens in a select.
   682  func TestNoRaceBlockedSelectSendSync(t *testing.T) {
   683  	c := make(chan *int, 1)
   684  	c <- nil
   685  	go func() {
   686  		i := 42
   687  		c <- &i
   688  	}()
   689  	time.Sleep(10 * time.Millisecond)
   690  	<-c
   691  	select {
   692  	case p := <-c:
   693  		if *p != 42 {
   694  			t.Fatal()
   695  		}
   696  	case <-make(chan int):
   697  	}
   698  }