17119: make controller understand filter groups.
[arvados.git] / sdk / go / asyncbuf / buf.go
index b3b9bf221a661450002a4a3c4bfc21e4063c5d0b..05af02f5f5dae3ec643fcd2a36216901b72defda 100644 (file)
@@ -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()
        }
 }