diff --git a/ioutils/readers.go b/ioutils/readers.go index 63f3c07..5a61e6b 100644 --- a/ioutils/readers.go +++ b/ioutils/readers.go @@ -4,8 +4,6 @@ import ( "crypto/sha256" "encoding/hex" "io" - - "golang.org/x/net/context" ) type readCloserWrapper struct { @@ -83,72 +81,3 @@ func (r *OnEOFReader) runFunc() { r.Fn = nil } } - -// cancelReadCloser wraps an io.ReadCloser with a context for cancelling read -// operations. -type cancelReadCloser struct { - cancel func() - pR *io.PipeReader // Stream to read from - pW *io.PipeWriter -} - -// NewCancelReadCloser creates a wrapper that closes the ReadCloser when the -// context is cancelled. The returned io.ReadCloser must be closed when it is -// no longer needed. -func NewCancelReadCloser(ctx context.Context, in io.ReadCloser) io.ReadCloser { - pR, pW := io.Pipe() - - // Create a context used to signal when the pipe is closed - doneCtx, cancel := context.WithCancel(context.Background()) - - p := &cancelReadCloser{ - cancel: cancel, - pR: pR, - pW: pW, - } - - go func() { - _, err := io.Copy(pW, in) - select { - case <-ctx.Done(): - // If the context was closed, p.closeWithError - // was already called. Calling it again would - // change the error that Read returns. - default: - p.closeWithError(err) - } - in.Close() - }() - go func() { - for { - select { - case <-ctx.Done(): - p.closeWithError(ctx.Err()) - case <-doneCtx.Done(): - return - } - } - }() - - return p -} - -// Read wraps the Read method of the pipe that provides data from the wrapped -// ReadCloser. -func (p *cancelReadCloser) Read(buf []byte) (n int, err error) { - return p.pR.Read(buf) -} - -// closeWithError closes the wrapper and its underlying reader. It will -// cause future calls to Read to return err. -func (p *cancelReadCloser) closeWithError(err error) { - p.pW.CloseWithError(err) - p.cancel() -} - -// Close closes the wrapper its underlying reader. It will cause -// future calls to Read to return io.EOF. -func (p *cancelReadCloser) Close() error { - p.closeWithError(io.EOF) - return nil -} diff --git a/ioutils/readers_test.go b/ioutils/readers_test.go index 9abc105..ff15d5a 100644 --- a/ioutils/readers_test.go +++ b/ioutils/readers_test.go @@ -2,12 +2,8 @@ package ioutils import ( "fmt" - "io/ioutil" "strings" "testing" - "time" - - "golang.org/x/net/context" ) // Implement io.Reader @@ -78,17 +74,3 @@ func (p *perpetualReader) Read(buf []byte) (n int, err error) { } return len(buf), nil } - -func TestCancelReadCloser(t *testing.T) { - ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) - cancelReadCloser := NewCancelReadCloser(ctx, ioutil.NopCloser(&perpetualReader{})) - for { - var buf [128]byte - _, err := cancelReadCloser.Read(buf[:]) - if err == context.DeadlineExceeded { - break - } else if err != nil { - t.Fatalf("got unexpected error: %v", err) - } - } -}