1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-01-08 10:45:04 +02:00
imgproxy/ctxreader/ctxreader.go

45 lines
722 B
Go

package ctxreader
import (
"context"
"io"
"sync"
"sync/atomic"
)
type ctxReader struct {
r io.ReadCloser
err atomic.Value
closeOnce sync.Once
}
func (r *ctxReader) Read(p []byte) (int, error) {
if err := r.err.Load(); err != nil {
return 0, err.(error)
}
return r.r.Read(p)
}
func (r *ctxReader) Close() (err error) {
r.closeOnce.Do(func() { err = r.r.Close() })
return
}
func New(ctx context.Context, r io.ReadCloser, closeOnDone bool) io.ReadCloser {
if ctx.Done() == nil {
return r
}
ctxr := ctxReader{r: r}
go func(ctx context.Context) {
<-ctx.Done()
ctxr.err.Store(ctx.Err())
if closeOnDone {
ctxr.closeOnce.Do(func() { ctxr.r.Close() })
}
}(ctx)
return &ctxr
}