mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-09-03 23:57:38 -04:00
pipe: Fix ListenPipe/DialPipe race
ListenPipe can fail if there is a concurrent DialPipe because there is a race window where DialPipe can connect to the initial server named pipe before it is connected to and closed by ListenPipe. To fix this, use the lower-level NT API for creating the server pipe, since this API allows for specifying that a server pipe should initially be in the disconnected state instead of the listening state. This allows us to avoid the race condition by creating the pipe in the correct state initially, so there is no longer a need to create a dummy client connection.
This commit is contained in:
@@ -514,3 +514,24 @@ func TestMessageReadMode(t *testing.T) {
|
||||
t.Fatalf("expected %s: %s", msg, vmsg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListenConnectRace(t *testing.T) {
|
||||
for i := 0; i < 50 && !t.Failed(); i++ {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
c, err := DialPipe(testPipeName, nil)
|
||||
if err == nil {
|
||||
c.Close()
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
s, err := ListenPipe(testPipeName, nil)
|
||||
if err != nil {
|
||||
t.Error(i, err)
|
||||
} else {
|
||||
s.Close()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user