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
5package race_test
6
7import (
8	"runtime"
9	"testing"
10	"time"
11)
12
13func 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
25func 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
37func 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
49func 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
61func 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
78func 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
90func 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
103func 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
120func 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
132func 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
145func 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
162func 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
181func 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
211func 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
225func 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
240func 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
268func 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
280func 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
301func 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
331func 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
350func 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
373func 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
394func 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
421func 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
440func 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
454func 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
474func 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
486func 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
513func 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
524func 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
537func 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
547func 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
558func 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
569func 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
580func 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
594func 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
608func 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
619func 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
636func 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
666func 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
683func 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.
703func 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.
723func 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.
743func 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
769func TestNoRaceElemSize0(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