libgo: update to go1.9
[official-gcc.git] / libgo / go / internal / poll / fd_mutex_test.go
blobbab81c6dfee53698b9a5660a7487ebc2c49c41d3
1 // Copyright 2013 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.
5 package poll_test
7 import (
8 . "internal/poll"
9 "math/rand"
10 "runtime"
11 "testing"
12 "time"
15 func TestMutexLock(t *testing.T) {
16 var mu FDMutex
18 if !mu.Incref() {
19 t.Fatal("broken")
21 if mu.Decref() {
22 t.Fatal("broken")
25 if !mu.RWLock(true) {
26 t.Fatal("broken")
28 if mu.RWUnlock(true) {
29 t.Fatal("broken")
32 if !mu.RWLock(false) {
33 t.Fatal("broken")
35 if mu.RWUnlock(false) {
36 t.Fatal("broken")
40 func TestMutexClose(t *testing.T) {
41 var mu FDMutex
42 if !mu.IncrefAndClose() {
43 t.Fatal("broken")
46 if mu.Incref() {
47 t.Fatal("broken")
49 if mu.RWLock(true) {
50 t.Fatal("broken")
52 if mu.RWLock(false) {
53 t.Fatal("broken")
55 if mu.IncrefAndClose() {
56 t.Fatal("broken")
60 func TestMutexCloseUnblock(t *testing.T) {
61 c := make(chan bool)
62 var mu FDMutex
63 mu.RWLock(true)
64 for i := 0; i < 4; i++ {
65 go func() {
66 if mu.RWLock(true) {
67 t.Error("broken")
68 return
70 c <- true
71 }()
73 // Concurrent goroutines must not be able to read lock the mutex.
74 time.Sleep(time.Millisecond)
75 select {
76 case <-c:
77 t.Fatal("broken")
78 default:
80 mu.IncrefAndClose() // Must unblock the readers.
81 for i := 0; i < 4; i++ {
82 select {
83 case <-c:
84 case <-time.After(10 * time.Second):
85 t.Fatal("broken")
88 if mu.Decref() {
89 t.Fatal("broken")
91 if !mu.RWUnlock(true) {
92 t.Fatal("broken")
96 func TestMutexPanic(t *testing.T) {
97 ensurePanics := func(f func()) {
98 defer func() {
99 if recover() == nil {
100 t.Fatal("does not panic")
106 var mu FDMutex
107 ensurePanics(func() { mu.Decref() })
108 ensurePanics(func() { mu.RWUnlock(true) })
109 ensurePanics(func() { mu.RWUnlock(false) })
111 ensurePanics(func() { mu.Incref(); mu.Decref(); mu.Decref() })
112 ensurePanics(func() { mu.RWLock(true); mu.RWUnlock(true); mu.RWUnlock(true) })
113 ensurePanics(func() { mu.RWLock(false); mu.RWUnlock(false); mu.RWUnlock(false) })
115 // ensure that it's still not broken
116 mu.Incref()
117 mu.Decref()
118 mu.RWLock(true)
119 mu.RWUnlock(true)
120 mu.RWLock(false)
121 mu.RWUnlock(false)
124 func TestMutexStress(t *testing.T) {
125 P := 8
126 N := int(1e6)
127 if testing.Short() {
128 P = 4
129 N = 1e4
131 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
132 done := make(chan bool)
133 var mu FDMutex
134 var readState [2]uint64
135 var writeState [2]uint64
136 for p := 0; p < P; p++ {
137 go func() {
138 r := rand.New(rand.NewSource(rand.Int63()))
139 for i := 0; i < N; i++ {
140 switch r.Intn(3) {
141 case 0:
142 if !mu.Incref() {
143 t.Error("broken")
144 return
146 if mu.Decref() {
147 t.Error("broken")
148 return
150 case 1:
151 if !mu.RWLock(true) {
152 t.Error("broken")
153 return
155 // Ensure that it provides mutual exclusion for readers.
156 if readState[0] != readState[1] {
157 t.Error("broken")
158 return
160 readState[0]++
161 readState[1]++
162 if mu.RWUnlock(true) {
163 t.Error("broken")
164 return
166 case 2:
167 if !mu.RWLock(false) {
168 t.Error("broken")
169 return
171 // Ensure that it provides mutual exclusion for writers.
172 if writeState[0] != writeState[1] {
173 t.Error("broken")
174 return
176 writeState[0]++
177 writeState[1]++
178 if mu.RWUnlock(false) {
179 t.Error("broken")
180 return
184 done <- true
187 for p := 0; p < P; p++ {
188 <-done
190 if !mu.IncrefAndClose() {
191 t.Fatal("broken")
193 if !mu.Decref() {
194 t.Fatal("broken")