Skip to content

Commit

Permalink
test/chan/doubleselect: fix various races
Browse files Browse the repository at this point in the history
There were duplicate closes and missing closes,
with the result that the program was rarely testing
as much as it seemed to be.  Now it finishes.

R=r
CC=golang-dev
https://golang.org/cl/4008046
  • Loading branch information
rsc committed Jan 21, 2011
1 parent 5b5a674 commit 0a5fc26
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions test/chan/doubleselect.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ var iterations *int = flag.Int("n", 100000, "number of iterations")
func sender(n int, c1, c2, c3, c4 chan<- int) {
defer close(c1)
defer close(c2)
defer close(c3)
defer close(c4)

for i := 0; i < n; i++ {
select {
Expand All @@ -35,26 +37,18 @@ func sender(n int, c1, c2, c3, c4 chan<- int) {
// mux receives the values from sender and forwards them onto another channel.
// It would be simplier to just have sender's four cases all be the same
// channel, but this doesn't actually trigger the bug.
func mux(out chan<- int, in <-chan int) {
for {
v := <-in
if closed(in) {
close(out)
break
}
func mux(out chan<- int, in <-chan int, done chan<- bool) {
for v := range in {
out <- v
}
done <- true
}

// recver gets a steam of values from the four mux's and checks for duplicates.
func recver(in <-chan int) {
seen := make(map[int]bool)

for {
v := <-in
if closed(in) {
break
}
for v := range in {
if _, ok := seen[v]; ok {
println("got duplicate value: ", v)
panic("fail")
Expand All @@ -70,15 +64,23 @@ func main() {
c2 := make(chan int)
c3 := make(chan int)
c4 := make(chan int)
done := make(chan bool)
cmux := make(chan int)
go sender(*iterations, c1, c2, c3, c4)
go mux(cmux, c1)
go mux(cmux, c2)
go mux(cmux, c3)
go mux(cmux, c4)
go mux(cmux, c1, done)
go mux(cmux, c2, done)
go mux(cmux, c3, done)
go mux(cmux, c4, done)
go func() {
<-done
<-done
<-done
<-done
close(cmux)
}()
// We keep the recver because it might catch more bugs in the future.
// However, the result of the bug linked to at the top is that we'll
// end up panicing with: "throw: bad g->status in ready".
// end up panicking with: "throw: bad g->status in ready".
recver(cmux)
print("PASS\n")
}

0 comments on commit 0a5fc26

Please sign in to comment.