diff --git a/file.go b/file.go index 99cc07fb..57ac3696 100644 --- a/file.go +++ b/file.go @@ -115,16 +115,18 @@ func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) { // closeHandle closes the resources associated with a Win32 handle func (f *win32File) closeHandle() { + f.wgLock.Lock() // Atomically set that we are closing, releasing the resources only once. if !f.closing.swap(true) { + f.wgLock.Unlock() // cancel all IO and wait for it to complete cancelIoEx(f.handle, nil) - f.wgLock.Lock() f.wg.Wait() - f.wgLock.Unlock() // at this point, no new IO can start syscall.Close(f.handle) f.handle = 0 + } else { + f.wgLock.Unlock() } } diff --git a/pipe_test.go b/pipe_test.go index 4c6208c1..3bc02dae 100644 --- a/pipe_test.go +++ b/pipe_test.go @@ -367,11 +367,11 @@ func TestEchoWithMessaging(t *testing.T) { OutputBufferSize: 65536, } l, err := ListenPipe(testPipeName, &c) - if err != nil { t.Fatal(err) } defer l.Close() + listenerDone := make(chan bool) clientDone := make(chan bool) go func() { @@ -380,6 +380,8 @@ func TestEchoWithMessaging(t *testing.T) { if e != nil { t.Fatal(e) } + defer conn.Close() + time.Sleep(500 * time.Millisecond) // make *sure* we don't begin to read before eof signal is sent io.Copy(conn, conn) conn.(CloseWriter).CloseWrite()