...
Run Format

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

Documentation: runtime/race/testdata

     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 TestRaceChanCloseLen(t *testing.T) {
   581  	v := 0
   582  	_ = v
   583  	c := make(chan int, 10)
   584  	c <- 0
   585  	go func() {
   586  		v = 1
   587  		close(c)
   588  	}()
   589  	time.Sleep(1e7)
   590  	_ = len(c)
   591  	v = 2
   592  }
   593  
   594  func TestRaceChanCloseSend(t *testing.T) {
   595  	compl := make(chan bool, 1)
   596  	c := make(chan int, 10)
   597  	go func() {
   598  		close(c)
   599  		compl <- true
   600  	}()
   601  	c <- 0
   602  	<-compl
   603  }
   604  
   605  func TestNoRaceChanMutex(t *testing.T) {
   606  	done := make(chan struct{})
   607  	mtx := make(chan struct{}, 1)
   608  	data := 0
   609  	_ = data
   610  	go func() {
   611  		mtx <- struct{}{}
   612  		data = 42
   613  		<-mtx
   614  		done <- struct{}{}
   615  	}()
   616  	mtx <- struct{}{}
   617  	data = 43
   618  	<-mtx
   619  	<-done
   620  }
   621  
   622  func TestNoRaceSelectMutex(t *testing.T) {
   623  	done := make(chan struct{})
   624  	mtx := make(chan struct{}, 1)
   625  	aux := make(chan bool)
   626  	data := 0
   627  	_ = data
   628  	go func() {
   629  		select {
   630  		case mtx <- struct{}{}:
   631  		case <-aux:
   632  		}
   633  		data = 42
   634  		select {
   635  		case <-mtx:
   636  		case <-aux:
   637  		}
   638  		done <- struct{}{}
   639  	}()
   640  	select {
   641  	case mtx <- struct{}{}:
   642  	case <-aux:
   643  	}
   644  	data = 43
   645  	select {
   646  	case <-mtx:
   647  	case <-aux:
   648  	}
   649  	<-done
   650  }
   651  
   652  func TestRaceChanSem(t *testing.T) {
   653  	done := make(chan struct{})
   654  	mtx := make(chan bool, 2)
   655  	data := 0
   656  	_ = data
   657  	go func() {
   658  		mtx <- true
   659  		data = 42
   660  		<-mtx
   661  		done <- struct{}{}
   662  	}()
   663  	mtx <- true
   664  	data = 43
   665  	<-mtx
   666  	<-done
   667  }
   668  
   669  func TestNoRaceChanWaitGroup(t *testing.T) {
   670  	const N = 10
   671  	chanWg := make(chan bool, N/2)
   672  	data := make([]int, N)
   673  	for i := 0; i < N; i++ {
   674  		chanWg <- true
   675  		go func(i int) {
   676  			data[i] = 42
   677  			<-chanWg
   678  		}(i)
   679  	}
   680  	for i := 0; i < cap(chanWg); i++ {
   681  		chanWg <- true
   682  	}
   683  	for i := 0; i < N; i++ {
   684  		_ = data[i]
   685  	}
   686  }
   687  
   688  // Test that sender synchronizes with receiver even if the sender was blocked.
   689  func TestNoRaceBlockedSendSync(t *testing.T) {
   690  	c := make(chan *int, 1)
   691  	c <- nil
   692  	go func() {
   693  		i := 42
   694  		c <- &i
   695  	}()
   696  	// Give the sender time to actually block.
   697  	// This sleep is completely optional: race report must not be printed
   698  	// regardless of whether the sender actually blocks or not.
   699  	// It cannot lead to flakiness.
   700  	time.Sleep(10 * time.Millisecond)
   701  	<-c
   702  	p := <-c
   703  	if *p != 42 {
   704  		t.Fatal()
   705  	}
   706  }
   707  
   708  // The same as TestNoRaceBlockedSendSync above, but sender unblock happens in a select.
   709  func TestNoRaceBlockedSelectSendSync(t *testing.T) {
   710  	c := make(chan *int, 1)
   711  	c <- nil
   712  	go func() {
   713  		i := 42
   714  		c <- &i
   715  	}()
   716  	time.Sleep(10 * time.Millisecond)
   717  	<-c
   718  	select {
   719  	case p := <-c:
   720  		if *p != 42 {
   721  			t.Fatal()
   722  		}
   723  	case <-make(chan int):
   724  	}
   725  }
   726  

View as plain text