| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- package ctxrw
- import (
- "context"
- g "github.com/anacrolix/generics"
- "io"
- )
- type contextedReader struct {
- ctx context.Context
- r io.Reader
- }
- func (me contextedReader) Read(p []byte) (n int, err error) {
- return contextedReadOrWrite(me.ctx, me.r.Read, p)
- }
- type contextedWriter struct {
- ctx context.Context
- w io.Writer
- }
- // This is problematic. If you return with a context error, a read or write is still pending, and
- // could mess up the stream.
- func contextedReadOrWrite(ctx context.Context, method func(b []byte) (int, error), b []byte) (_ int, err error) {
- asyncCh := make(chan g.Result[int], 1)
- go func() {
- asyncCh <- g.ResultFromTuple(method(b))
- }()
- select {
- case <-ctx.Done():
- err = context.Cause(ctx)
- return
- case res := <-asyncCh:
- return res.AsTuple()
- }
- }
- func (me contextedWriter) Write(p []byte) (n int, err error) {
- return contextedReadOrWrite(me.ctx, me.w.Write, p)
- }
- func WrapReadWriter(ctx context.Context, rw io.ReadWriter) io.ReadWriter {
- return struct {
- io.Reader
- io.Writer
- }{
- contextedReader{
- ctx: ctx,
- r: rw,
- },
- contextedWriter{
- ctx: ctx,
- w: rw,
- },
- }
- }
|