X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/abc241fb83523ae5ae5905ae47210f15d7e0671c..9d74b115e05fac77b49d080d9c89699b12f3c433:/sdk/go/asyncbuf/buf.go diff --git a/sdk/go/asyncbuf/buf.go b/sdk/go/asyncbuf/buf.go index b3b9bf221a..05af02f5f5 100644 --- a/sdk/go/asyncbuf/buf.go +++ b/sdk/go/asyncbuf/buf.go @@ -86,16 +86,23 @@ type reader struct { func (r *reader) Read(p []byte) (int, error) { r.b.cond.L.Lock() - defer r.b.cond.L.Unlock() for { - if r.b.data.Len() > r.read || len(p) == 0 { - n := copy(p, r.b.data.Bytes()[r.read:]) + switch { + case r.read < r.b.data.Len(): + buf := r.b.data.Bytes() + r.b.cond.L.Unlock() + n := copy(p, buf[r.read:]) r.read += n return n, nil + case r.b.err != nil || len(p) == 0: + // r.b.err != nil means we reached EOF. And + // even if we're not at EOF, there's no need + // to block if len(p)==0. + err := r.b.err + r.b.cond.L.Unlock() + return 0, err + default: + r.b.cond.Wait() } - if r.b.err != nil { - return 0, r.b.err - } - r.b.cond.Wait() } }