github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/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  	done := make(chan bool)
   289  	go func() {
   290  		defer func() {
   291  			recover()
   292  		}()
   293  		v1 = 1
   294  		c <- 1
   295  		done <- true
   296  	}()
   297  	go func() {
   298  		time.Sleep(1e7)
   299  		v2 = 2
   300  		close(c)
   301  		done <- true
   302  	}()
   303  	time.Sleep(2e7)
   304  	if _, who := <-c; who {
   305  		v2 = 2
   306  	} else {
   307  		v1 = 2
   308  	}
   309  	<-done
   310  	<-done
   311  }
   312  
   313  func TestRaceChanSendClose(t *testing.T) {
   314  	compl := make(chan bool, 2)
   315  	c := make(chan int, 1)
   316  	go func() {
   317  		defer func() {
   318  			recover()
   319  			compl <- true
   320  		}()
   321  		c <- 1
   322  	}()
   323  	go func() {
   324  		time.Sleep(10 * time.Millisecond)
   325  		close(c)
   326  		compl <- true
   327  	}()
   328  	<-compl
   329  	<-compl
   330  }
   331  
   332  func TestRaceChanSendSelectClose(t *testing.T) {
   333  	compl := make(chan bool, 2)
   334  	c := make(chan int, 1)
   335  	c1 := make(chan int)
   336  	go func() {
   337  		defer func() {
   338  			recover()
   339  			compl <- true
   340  		}()
   341  		time.Sleep(10 * time.Millisecond)
   342  		select {
   343  		case c <- 1:
   344  		case <-c1:
   345  		}
   346  	}()
   347  	go func() {
   348  		close(c)
   349  		compl <- true
   350  	}()
   351  	<-compl
   352  	<-compl
   353  }
   354  
   355  func TestRaceSelectReadWriteAsync(t *testing.T) {
   356  	done := make(chan bool)
   357  	x := 0
   358  	c1 := make(chan int, 10)
   359  	c2 := make(chan int, 10)
   360  	c3 := make(chan int)
   361  	c2 <- 1
   362  	go func() {
   363  		select {
   364  		case c1 <- x: // read of x races with...
   365  		case c3 <- 1:
   366  		}
   367  		done <- true
   368  	}()
   369  	select {
   370  	case x = <-c2: // ... write to x here
   371  	case c3 <- 1:
   372  	}
   373  	<-done
   374  }
   375  
   376  func TestRaceSelectReadWriteSync(t *testing.T) {
   377  	done := make(chan bool)
   378  	x := 0
   379  	c1 := make(chan int)
   380  	c2 := make(chan int)
   381  	c3 := make(chan int)
   382  	// make c1 and c2 ready for communication
   383  	go func() {
   384  		<-c1
   385  	}()
   386  	go func() {
   387  		c2 <- 1
   388  	}()
   389  	go func() {
   390  		select {
   391  		case c1 <- x: // read of x races with...
   392  		case c3 <- 1:
   393  		}
   394  		done <- true
   395  	}()
   396  	select {
   397  	case x = <-c2: // ... write to x here
   398  	case c3 <- 1:
   399  	}
   400  	<-done
   401  }
   402  
   403  func TestNoRaceSelectReadWriteAsync(t *testing.T) {
   404  	done := make(chan bool)
   405  	x := 0
   406  	c1 := make(chan int)
   407  	c2 := make(chan int)
   408  	go func() {
   409  		select {
   410  		case c1 <- x: // read of x does not race with...
   411  		case c2 <- 1:
   412  		}
   413  		done <- true
   414  	}()
   415  	select {
   416  	case x = <-c1: // ... write to x here
   417  	case c2 <- 1:
   418  	}
   419  	<-done
   420  }
   421  
   422  func TestRaceChanReadWriteAsync(t *testing.T) {
   423  	done := make(chan bool)
   424  	c1 := make(chan int, 10)
   425  	c2 := make(chan int, 10)
   426  	c2 <- 10
   427  	x := 0
   428  	go func() {
   429  		c1 <- x // read of x races with...
   430  		done <- true
   431  	}()
   432  	x = <-c2 // ... write to x here
   433  	<-done
   434  }
   435  
   436  func TestRaceChanReadWriteSync(t *testing.T) {
   437  	done := make(chan bool)
   438  	c1 := make(chan int)
   439  	c2 := make(chan int)
   440  	// make c1 and c2 ready for communication
   441  	go func() {
   442  		<-c1
   443  	}()
   444  	go func() {
   445  		c2 <- 10
   446  	}()
   447  	x := 0
   448  	go func() {
   449  		c1 <- x // read of x races with...
   450  		done <- true
   451  	}()
   452  	x = <-c2 // ... write to x here
   453  	<-done
   454  }
   455  
   456  func TestNoRaceChanReadWriteAsync(t *testing.T) {
   457  	done := make(chan bool)
   458  	c1 := make(chan int, 10)
   459  	x := 0
   460  	go func() {
   461  		c1 <- x // read of x does not race with...
   462  		done <- true
   463  	}()
   464  	x = <-c1 // ... write to x here
   465  	<-done
   466  }
   467  
   468  func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
   469  	type Task struct {
   470  		f    func()
   471  		done chan bool
   472  	}
   473  
   474  	queue := make(chan Task)
   475  
   476  	go func() {
   477  		t := <-queue
   478  		t.f()
   479  		t.done <- true
   480  	}()
   481  
   482  	doit := func(f func()) {
   483  		done := make(chan bool, 1)
   484  		queue <- Task{f, done}
   485  		<-done
   486  	}
   487  
   488  	x := 0
   489  	doit(func() {
   490  		x = 1
   491  	})
   492  	_ = x
   493  }
   494  
   495  func TestRaceChanItselfSend(t *testing.T) {
   496  	compl := make(chan bool, 1)
   497  	c := make(chan int, 10)
   498  	go func() {
   499  		c <- 0
   500  		compl <- true
   501  	}()
   502  	c = make(chan int, 20)
   503  	<-compl
   504  }
   505  
   506  func TestRaceChanItselfRecv(t *testing.T) {
   507  	compl := make(chan bool, 1)
   508  	c := make(chan int, 10)
   509  	c <- 1
   510  	go func() {
   511  		<-c
   512  		compl <- true
   513  	}()
   514  	time.Sleep(1e7)
   515  	c = make(chan int, 20)
   516  	<-compl
   517  }
   518  
   519  func TestRaceChanItselfNil(t *testing.T) {
   520  	c := make(chan int, 10)
   521  	go func() {
   522  		c <- 0
   523  	}()
   524  	time.Sleep(1e7)
   525  	c = nil
   526  	_ = c
   527  }
   528  
   529  func TestRaceChanItselfClose(t *testing.T) {
   530  	compl := make(chan bool, 1)
   531  	c := make(chan int)
   532  	go func() {
   533  		close(c)
   534  		compl <- true
   535  	}()
   536  	c = make(chan int)
   537  	<-compl
   538  }
   539  
   540  func TestRaceChanItselfLen(t *testing.T) {
   541  	compl := make(chan bool, 1)
   542  	c := make(chan int)
   543  	go func() {
   544  		_ = len(c)
   545  		compl <- true
   546  	}()
   547  	c = make(chan int)
   548  	<-compl
   549  }
   550  
   551  func TestRaceChanItselfCap(t *testing.T) {
   552  	compl := make(chan bool, 1)
   553  	c := make(chan int)
   554  	go func() {
   555  		_ = cap(c)
   556  		compl <- true
   557  	}()
   558  	c = make(chan int)
   559  	<-compl
   560  }
   561  
   562  func TestRaceChanCloseLen(t *testing.T) {
   563  	v := 0
   564  	c := make(chan int, 10)
   565  	c <- 0
   566  	go func() {
   567  		v = 1
   568  		close(c)
   569  	}()
   570  	time.Sleep(1e7)
   571  	_ = len(c)
   572  	v = 2
   573  }
   574  
   575  func TestRaceChanCloseSend(t *testing.T) {
   576  	compl := make(chan bool, 1)
   577  	c := make(chan int, 10)
   578  	go func() {
   579  		close(c)
   580  		compl <- true
   581  	}()
   582  	c <- 0
   583  	<-compl
   584  }
   585  
   586  func TestNoRaceChanMutex(t *testing.T) {
   587  	done := make(chan struct{})
   588  	mtx := make(chan struct{}, 1)
   589  	data := 0
   590  	go func() {
   591  		mtx <- struct{}{}
   592  		data = 42
   593  		<-mtx
   594  		done <- struct{}{}
   595  	}()
   596  	mtx <- struct{}{}
   597  	data = 43
   598  	<-mtx
   599  	<-done
   600  }
   601  
   602  func TestNoRaceSelectMutex(t *testing.T) {
   603  	done := make(chan struct{})
   604  	mtx := make(chan struct{}, 1)
   605  	aux := make(chan bool)
   606  	data := 0
   607  	go func() {
   608  		select {
   609  		case mtx <- struct{}{}:
   610  		case <-aux:
   611  		}
   612  		data = 42
   613  		select {
   614  		case <-mtx:
   615  		case <-aux:
   616  		}
   617  		done <- struct{}{}
   618  	}()
   619  	select {
   620  	case mtx <- struct{}{}:
   621  	case <-aux:
   622  	}
   623  	data = 43
   624  	select {
   625  	case <-mtx:
   626  	case <-aux:
   627  	}
   628  	<-done
   629  }
   630  
   631  func TestRaceChanSem(t *testing.T) {
   632  	done := make(chan struct{})
   633  	mtx := make(chan bool, 2)
   634  	data := 0
   635  	go func() {
   636  		mtx <- true
   637  		data = 42
   638  		<-mtx
   639  		done <- struct{}{}
   640  	}()
   641  	mtx <- true
   642  	data = 43
   643  	<-mtx
   644  	<-done
   645  }
   646  
   647  func TestNoRaceChanWaitGroup(t *testing.T) {
   648  	const N = 10
   649  	chanWg := make(chan bool, N/2)
   650  	data := make([]int, N)
   651  	for i := 0; i < N; i++ {
   652  		chanWg <- true
   653  		go func(i int) {
   654  			data[i] = 42
   655  			<-chanWg
   656  		}(i)
   657  	}
   658  	for i := 0; i < cap(chanWg); i++ {
   659  		chanWg <- true
   660  	}
   661  	for i := 0; i < N; i++ {
   662  		_ = data[i]
   663  	}
   664  }
   665  
   666  // Test that sender synchronizes with receiver even if the sender was blocked.
   667  func TestNoRaceBlockedSendSync(t *testing.T) {
   668  	c := make(chan *int, 1)
   669  	c <- nil
   670  	go func() {
   671  		i := 42
   672  		c <- &i
   673  	}()
   674  	// Give the sender time to actually block.
   675  	// This sleep is completely optional: race report must not be printed
   676  	// regardless of whether the sender actually blocks or not.
   677  	// It cannot lead to flakiness.
   678  	time.Sleep(10 * time.Millisecond)
   679  	<-c
   680  	p := <-c
   681  	if *p != 42 {
   682  		t.Fatal()
   683  	}
   684  }
   685  
   686  // The same as TestNoRaceBlockedSendSync above, but sender unblock happens in a select.
   687  func TestNoRaceBlockedSelectSendSync(t *testing.T) {
   688  	c := make(chan *int, 1)
   689  	c <- nil
   690  	go func() {
   691  		i := 42
   692  		c <- &i
   693  	}()
   694  	time.Sleep(10 * time.Millisecond)
   695  	<-c
   696  	select {
   697  	case p := <-c:
   698  		if *p != 42 {
   699  			t.Fatal()
   700  		}
   701  	case <-make(chan int):
   702  	}
   703  }