From: Mikio Hara Date: Wed, 13 May 2015 05:06:43 +0000 (+0900) Subject: net/internal/socktest: fix data race X-Git-Tag: go1.5beta1~609 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=645e77ef10ef2367ab07669dc4e8be5b54d36fe7;p=gostls13.git net/internal/socktest: fix data race Fixes #10796. Change-Id: Ifcd2e771c64114e210fbfc5efaaceb53c534f745 Reviewed-on: https://go-review.googlesource.com/10007 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go index 3ae1c6be3c..60e581f463 100644 --- a/src/net/internal/socktest/main_test.go +++ b/src/net/internal/socktest/main_test.go @@ -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 }, diff --git a/src/net/internal/socktest/switch.go b/src/net/internal/socktest/switch.go index 5e558a2de3..4e38c7a85f 100644 --- a/src/net/internal/socktest/switch.go +++ b/src/net/internal/socktest/switch.go @@ -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() diff --git a/src/net/internal/socktest/switch_unix.go b/src/net/internal/socktest/switch_unix.go index 2b89276fa1..14c0c228a2 100644 --- a/src/net/internal/socktest/switch_unix.go +++ b/src/net/internal/socktest/switch_unix.go @@ -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 diff --git a/src/net/internal/socktest/switch_windows.go b/src/net/internal/socktest/switch_windows.go index 3cee49ba0b..4f1d597a27 100644 --- a/src/net/internal/socktest/switch_windows.go +++ b/src/net/internal/socktest/switch_windows.go @@ -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 diff --git a/src/net/internal/socktest/sys_unix.go b/src/net/internal/socktest/sys_unix.go index 4089f8cea2..f983e266f1 100644 --- a/src/net/internal/socktest/sys_unix.go +++ b/src/net/internal/socktest/sys_unix.go @@ -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] diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go index 907e01b5a2..07af0e7046 100644 --- a/src/net/internal/socktest/sys_windows.go +++ b/src/net/internal/socktest/sys_windows.go @@ -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]