3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Test the situation in which two cases of a select can
8 // both end up running. See http://codereview.appspot.com/180068.
17 var iterations *int = flag.Int("n", 100000, "number of iterations")
19 // sender sends a counter to one of four different channels. If two
20 // cases both end up running in the same iteration, the same value will be sent
21 // to two different channels.
22 func sender(n int, c1, c2, c3, c4 chan<- int) {
28 for i := 0; i < n; i++ {
38 // mux receives the values from sender and forwards them onto another channel.
39 // It would be simpler to just have sender's four cases all be the same
40 // channel, but this doesn't actually trigger the bug.
41 func mux(out chan<- int, in <-chan int, done chan<- bool) {
48 // recver gets a steam of values from the four mux's and checks for duplicates.
49 func recver(in <-chan int) {
50 seen := make(map[int]bool)
53 if _, ok := seen[v]; ok {
54 println("got duplicate value: ", v)
69 done := make(chan bool)
70 cmux := make(chan int)
71 go sender(*iterations, c1, c2, c3, c4)
72 go mux(cmux, c1, done)
73 go mux(cmux, c2, done)
74 go mux(cmux, c3, done)
75 go mux(cmux, c4, done)
83 // We keep the recver because it might catch more bugs in the future.
84 // However, the result of the bug linked to at the top is that we'll
85 // end up panicking with: "throw: bad g->status in ready".