Source file src/runtime/race/testdata/chan_test.go

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

View as plain text