mirror of
https://github.com/golang/go
synced 2024-11-18 07:24:45 -07:00
ac2f84d524
This change makes unexposed methods start with lowercase letters for avoiding unnecessary confusion because the net package uses many embedding structures and intrefaces for controlling exposure of APIs. Note that this change leaves DNS-related methods as they are. Change-Id: I253758d1659175c5d0af6b2efcd30ce83f46543d Reviewed-on: https://go-review.googlesource.com/20784 Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
196 lines
3.4 KiB
Go
196 lines
3.4 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package net
|
|
|
|
import (
|
|
"math/rand"
|
|
"runtime"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestMutexLock(t *testing.T) {
|
|
var mu fdMutex
|
|
|
|
if !mu.incref() {
|
|
t.Fatal("broken")
|
|
}
|
|
if mu.decref() {
|
|
t.Fatal("broken")
|
|
}
|
|
|
|
if !mu.rwlock(true) {
|
|
t.Fatal("broken")
|
|
}
|
|
if mu.rwunlock(true) {
|
|
t.Fatal("broken")
|
|
}
|
|
|
|
if !mu.rwlock(false) {
|
|
t.Fatal("broken")
|
|
}
|
|
if mu.rwunlock(false) {
|
|
t.Fatal("broken")
|
|
}
|
|
}
|
|
|
|
func TestMutexClose(t *testing.T) {
|
|
var mu fdMutex
|
|
if !mu.increfAndClose() {
|
|
t.Fatal("broken")
|
|
}
|
|
|
|
if mu.incref() {
|
|
t.Fatal("broken")
|
|
}
|
|
if mu.rwlock(true) {
|
|
t.Fatal("broken")
|
|
}
|
|
if mu.rwlock(false) {
|
|
t.Fatal("broken")
|
|
}
|
|
if mu.increfAndClose() {
|
|
t.Fatal("broken")
|
|
}
|
|
}
|
|
|
|
func TestMutexCloseUnblock(t *testing.T) {
|
|
c := make(chan bool)
|
|
var mu fdMutex
|
|
mu.rwlock(true)
|
|
for i := 0; i < 4; i++ {
|
|
go func() {
|
|
if mu.rwlock(true) {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
c <- true
|
|
}()
|
|
}
|
|
// Concurrent goroutines must not be able to read lock the mutex.
|
|
time.Sleep(time.Millisecond)
|
|
select {
|
|
case <-c:
|
|
t.Fatal("broken")
|
|
default:
|
|
}
|
|
mu.increfAndClose() // Must unblock the readers.
|
|
for i := 0; i < 4; i++ {
|
|
select {
|
|
case <-c:
|
|
case <-time.After(10 * time.Second):
|
|
t.Fatal("broken")
|
|
}
|
|
}
|
|
if mu.decref() {
|
|
t.Fatal("broken")
|
|
}
|
|
if !mu.rwunlock(true) {
|
|
t.Fatal("broken")
|
|
}
|
|
}
|
|
|
|
func TestMutexPanic(t *testing.T) {
|
|
ensurePanics := func(f func()) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Fatal("does not panic")
|
|
}
|
|
}()
|
|
f()
|
|
}
|
|
|
|
var mu fdMutex
|
|
ensurePanics(func() { mu.decref() })
|
|
ensurePanics(func() { mu.rwunlock(true) })
|
|
ensurePanics(func() { mu.rwunlock(false) })
|
|
|
|
ensurePanics(func() { mu.incref(); mu.decref(); mu.decref() })
|
|
ensurePanics(func() { mu.rwlock(true); mu.rwunlock(true); mu.rwunlock(true) })
|
|
ensurePanics(func() { mu.rwlock(false); mu.rwunlock(false); mu.rwunlock(false) })
|
|
|
|
// ensure that it's still not broken
|
|
mu.incref()
|
|
mu.decref()
|
|
mu.rwlock(true)
|
|
mu.rwunlock(true)
|
|
mu.rwlock(false)
|
|
mu.rwunlock(false)
|
|
}
|
|
|
|
func TestMutexStress(t *testing.T) {
|
|
P := 8
|
|
N := int(1e6)
|
|
if testing.Short() {
|
|
P = 4
|
|
N = 1e4
|
|
}
|
|
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
|
|
done := make(chan bool)
|
|
var mu fdMutex
|
|
var readState [2]uint64
|
|
var writeState [2]uint64
|
|
for p := 0; p < P; p++ {
|
|
go func() {
|
|
r := rand.New(rand.NewSource(rand.Int63()))
|
|
for i := 0; i < N; i++ {
|
|
switch r.Intn(3) {
|
|
case 0:
|
|
if !mu.incref() {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
if mu.decref() {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
case 1:
|
|
if !mu.rwlock(true) {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
// Ensure that it provides mutual exclusion for readers.
|
|
if readState[0] != readState[1] {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
readState[0]++
|
|
readState[1]++
|
|
if mu.rwunlock(true) {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
case 2:
|
|
if !mu.rwlock(false) {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
// Ensure that it provides mutual exclusion for writers.
|
|
if writeState[0] != writeState[1] {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
writeState[0]++
|
|
writeState[1]++
|
|
if mu.rwunlock(false) {
|
|
t.Error("broken")
|
|
return
|
|
}
|
|
}
|
|
}
|
|
done <- true
|
|
}()
|
|
}
|
|
for p := 0; p < P; p++ {
|
|
<-done
|
|
}
|
|
if !mu.increfAndClose() {
|
|
t.Fatal("broken")
|
|
}
|
|
if !mu.decref() {
|
|
t.Fatal("broken")
|
|
}
|
|
}
|