1 // $G $D/$F.go && $L $F.$A && ./$A.out
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 // This test is designed to flush out the case where two cases of a select can
8 // both end up running. See http://codereview.appspot.com/180068.
16 var iterations *int = flag.Int("n", 100000, "number of iterations")
18 // sender sends a counter to one of four different channels. If two
19 // cases both end up running in the same iteration, the same value will be sent
20 // to two different channels.
21 func sender(n int, c1, c2, c3, c4 chan<- int) {
25 for i := 0; i < n; i++ {
35 // mux receives the values from sender and forwards them onto another channel.
36 // It would be simplier to just have sender's four cases all be the same
37 // channel, but this doesn't actually trigger the bug.
38 func mux(out chan<- int, in <-chan int) {
49 // recver gets a steam of values from the four mux's and checks for duplicates.
50 func recver(in <-chan int) {
51 seen := make(map[int]bool)
58 if _, ok := seen[v]; ok {
59 println("got duplicate value: ", v)
73 cmux := make(chan int)
74 go sender(*iterations, c1, c2, c3, c4)
79 // We keep the recver because it might catch more bugs in the future.
80 // However, the result of the bug linked to at the top is that we'll
81 // end up panicing with: "throw: bad g->status in ready".