]> Cypherpunks repositories - gostls13.git/commitdiff
net/internal/socktest: fix data race
authorMikio Hara <mikioh.mikioh@gmail.com>
Wed, 13 May 2015 05:06:43 +0000 (14:06 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Wed, 13 May 2015 21:38:34 +0000 (21:38 +0000)
Fixes #10796.

Change-Id: Ifcd2e771c64114e210fbfc5efaaceb53c534f745
Reviewed-on: https://go-review.googlesource.com/10007
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/internal/socktest/main_test.go
src/net/internal/socktest/switch.go
src/net/internal/socktest/switch_unix.go
src/net/internal/socktest/switch_windows.go
src/net/internal/socktest/sys_unix.go
src/net/internal/socktest/sys_windows.go

index 3ae1c6be3c84a98f99f31af68807ea0f7012b05b..60e581f463c27779af13d49d6183a860317e5b3a 100644 (file)
@@ -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 },
index 5e558a2de327dfdcfcb1d45436677f6bae515073..4e38c7a85f3aa68009735204f6ef8c03718d5151 100644 (file)
@@ -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()
index 2b89276fa113c0b3b030eadb1a00b706797ac44e..14c0c228a2f1e277c1cf428bc1dddb99744e4ce8 100644 (file)
@@ -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
index 3cee49ba0b5f90009495b7d5fa818659cce39a5b..4f1d597a27af777b86b890bd5d0e488cdcbe1eb3 100644 (file)
@@ -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
index 4089f8cea2368e8fd3f5de499dd998e86ebf72e4..f983e266f16fea934da436a1b4f5ddbd06e858e8 100644 (file)
@@ -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]
index 907e01b5a2e8d626a015b8d783fbaeede7088b66..07af0e70468a87a87d29761081871cb2f1690659 100644 (file)
@@ -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]