mirror of
https://github.com/golang/go
synced 2024-10-02 14:28:38 -06:00
net: fix concurrent Accept on windows
Runtime netpoll supports at most one read waiter and at most one write waiter. It's responsibility of net package to ensure that. Currently windows implementation allows more than one waiter in Accept. It leads to "fatal error: netpollblock: double wait". R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/12400045
This commit is contained in:
parent
910caf9345
commit
77f21eea59
@ -579,6 +579,8 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
|
||||
}
|
||||
|
||||
// Submit accept request.
|
||||
fd.rio.Lock()
|
||||
defer fd.rio.Unlock()
|
||||
var o acceptOp
|
||||
o.Init(fd, 'r')
|
||||
o.newsock = s
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@ -294,3 +295,35 @@ func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
|
||||
<-done
|
||||
}
|
||||
}
|
||||
|
||||
func TestTCPConcurrentAccept(t *testing.T) {
|
||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
|
||||
ln, err := Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("Listen failed: %v", err)
|
||||
}
|
||||
const N = 10
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(N)
|
||||
for i := 0; i < N; i++ {
|
||||
go func() {
|
||||
for {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
for i := 0; i < 10*N; i++ {
|
||||
c, err := Dial("tcp", ln.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("Dial failed: %v", err)
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
ln.Close()
|
||||
wg.Wait()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user