github.com/haraldrudell/parl@v0.4.176/pio/close-callbacker.go (about) 1 /* 2 © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package pio 7 8 import ( 9 "io" 10 11 "github.com/haraldrudell/parl" 12 "github.com/haraldrudell/parl/perrors" 13 ) 14 15 // Go does not allow promotion of a type parameter 16 // https://github.com/golang/go/issues/49030 17 // interfaces: 18 var _ io.ReadCloser 19 var _ io.ReadSeekCloser 20 var _ io.ReadWriteCloser 21 var _ io.WriteCloser 22 var _ io.Closer 23 24 type CloseCallback func(err error) (e error) 25 26 // CloseCallbacker implements a close callback for io.Closer 27 // 231128 unused 28 type CloseCallbacker struct { 29 closer io.Closer 30 closeCallback CloseCallback 31 isClosed parl.Awaitable 32 } 33 34 var _ io.Closer = &CloseCallbacker{} 35 36 func NewCloseCallbacker(closer io.Closer, closeCallback CloseCallback) (closeCallbacker *CloseCallbacker) { 37 if closer == nil { 38 panic(parl.NilError("closer")) 39 } else if closeCallback == nil { 40 panic(parl.NilError("closeCallback")) 41 } 42 return &CloseCallbacker{ 43 closer: closer, 44 closeCallback: closeCallback, 45 } 46 } 47 48 func (c *CloseCallbacker) Close() (err error) { 49 if !c.isClosed.Close() { 50 return // already closed 51 } 52 parl.Close(c.closer, &err) 53 var e = c.invokeCloseCallback(err) 54 if e != nil && e != err { 55 err = perrors.AppendError(err, e) 56 } 57 return 58 } 59 60 func (c *CloseCallbacker) IsClosed() (isClosed bool) { return c.isClosed.IsClosed() } 61 62 func (c *CloseCallbacker) Wait() { <-c.isClosed.Ch() } 63 64 func (c *CloseCallbacker) invokeCloseCallback(e error) (err error) { 65 defer parl.RecoverErr(func() parl.DA { return parl.A() }, &err) 66 67 err = c.closeCallback(e) 68 69 return 70 }