mirror of https://github.com/golang/go.git
net/internal/socktest: fix data race
Fixes #10796. Change-Id: Ifcd2e771c64114e210fbfc5efaaceb53c534f745 Reviewed-on: https://go-review.googlesource.com/10007 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
647026a16b
commit
645e77ef10
|
|
@ -9,6 +9,7 @@ package socktest_test
|
|||
import (
|
||||
"net/internal/socktest"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
|
@ -27,6 +28,21 @@ func TestMain(m *testing.M) {
|
|||
os.Exit(st)
|
||||
}
|
||||
|
||||
func TestSwitch(t *testing.T) {
|
||||
const N = 10
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for _, family := range []int{syscall.AF_INET, syscall.AF_INET6} {
|
||||
socketFunc(family, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestSocket(t *testing.T) {
|
||||
for _, f := range []socktest.Filter{
|
||||
func(st *socktest.Status) (socktest.AfterFilter, error) { return nil, nil },
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
func switchInit(sw *Switch) {
|
||||
sw.fltab = make(map[FilterType]Filter)
|
||||
sw.sotab = make(Sockets)
|
||||
sw.stats = make(stats)
|
||||
}
|
||||
|
||||
// A Switch represents a callpath point switch for socket system
|
||||
// calls.
|
||||
type Switch struct {
|
||||
|
|
@ -29,6 +23,12 @@ type Switch struct {
|
|||
stats stats
|
||||
}
|
||||
|
||||
func (sw *Switch) init() {
|
||||
sw.fltab = make(map[FilterType]Filter)
|
||||
sw.sotab = make(Sockets)
|
||||
sw.stats = make(stats)
|
||||
}
|
||||
|
||||
// Stats returns a list of per-cookie socket statistics.
|
||||
func (sw *Switch) Stats() []Stat {
|
||||
var st []Stat
|
||||
|
|
@ -162,7 +162,7 @@ func (f AfterFilter) apply(st *Status) error {
|
|||
|
||||
// Set deploys the socket system call filter f for the filter type t.
|
||||
func (sw *Switch) Set(t FilterType, f Filter) {
|
||||
sw.once.Do(func() { switchInit(sw) })
|
||||
sw.once.Do(sw.init)
|
||||
sw.fmu.Lock()
|
||||
sw.fltab[t] = f
|
||||
sw.fmu.Unlock()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ func (sw *Switch) sockso(s int) *Status {
|
|||
// addLocked returns a new Status without locking.
|
||||
// sw.smu must be held before call.
|
||||
func (sw *Switch) addLocked(s, family, sotype, proto int) *Status {
|
||||
sw.once.Do(func() { switchInit(sw) })
|
||||
sw.once.Do(sw.init)
|
||||
so := Status{Cookie: cookie(family, sotype, proto)}
|
||||
sw.sotab[s] = so
|
||||
return &so
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ func (sw *Switch) sockso(s syscall.Handle) *Status {
|
|||
// addLocked returns a new Status without locking.
|
||||
// sw.smu must be held before call.
|
||||
func (sw *Switch) addLocked(s syscall.Handle, family, sotype, proto int) *Status {
|
||||
sw.once.Do(func() { switchInit(sw) })
|
||||
sw.once.Do(sw.init)
|
||||
so := Status{Cookie: cookie(family, sotype, proto)}
|
||||
sw.sotab[s] = so
|
||||
return &so
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import "syscall"
|
|||
|
||||
// Socket wraps syscall.Socket.
|
||||
func (sw *Switch) Socket(family, sotype, proto int) (s int, err error) {
|
||||
sw.once.Do(sw.init)
|
||||
|
||||
so := &Status{Cookie: cookie(family, sotype, proto)}
|
||||
sw.fmu.RLock()
|
||||
f, _ := sw.fltab[FilterSocket]
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import "syscall"
|
|||
|
||||
// Socket wraps syscall.Socket.
|
||||
func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) {
|
||||
sw.once.Do(sw.init)
|
||||
|
||||
so := &Status{Cookie: cookie(family, sotype, proto)}
|
||||
sw.fmu.RLock()
|
||||
f, _ := sw.fltab[FilterSocket]
|
||||
|
|
|
|||
Loading…
Reference in New Issue