From b66a064ddfb8f613c876e7bafddcbe0dce280730 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Wed, 29 Oct 2025 21:24:06 +0100 Subject: [PATCH] don't panic on double close --- pipeat.go | 14 ++++++++++---- pipeat_test.go | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/pipeat.go b/pipeat.go index 549a8a7..a092a29 100644 --- a/pipeat.go +++ b/pipeat.go @@ -102,8 +102,11 @@ func (f *pipeFile) readerror() error { func (f *pipeFile) setReaderror(err error) { f.dataLock.Lock() defer f.dataLock.Unlock() - f.rerr = err - close(f.eor) + + if f.rerr == nil { + f.rerr = err + close(f.eor) + } f.rCond.Broadcast() f.wCond.Broadcast() } @@ -148,8 +151,11 @@ func (f *pipeFile) writeerror() error { func (f *pipeFile) setWriteerror(err error) { f.dataLock.Lock() defer f.dataLock.Unlock() - f.werr = err - close(f.eow) + + if f.werr == nil { + f.werr = err + close(f.eow) + } f.rCond.Broadcast() f.wCond.Broadcast() } diff --git a/pipeat_test.go b/pipeat_test.go index a7cff4a..f909671 100644 --- a/pipeat_test.go +++ b/pipeat_test.go @@ -7,6 +7,7 @@ import ( "bytes" "errors" "io" + "io/fs" "math/rand" "strings" "sync" @@ -534,3 +535,19 @@ func TestUnlockWriteOnWriterClose(t *testing.T) { assert.Equal(t, errTest, err) r.Close() } + +func TestDoubleClose(t *testing.T) { + r, w, err := Pipe() + if err != nil { + panic(err) + } + err = r.Close() + assert.NoError(t, err) + err = w.Close() + assert.NoError(t, err) + + err = r.Close() + assert.ErrorIs(t, err, fs.ErrClosed) + err = w.Close() + assert.NoError(t, err) +}