зеркало из https://github.com/docker/engine-api.git
cancellable: use sync.Once to prevent double channel close
Signed-off-by: Alexander Morozov <lk4d4math@gmail.com>
This commit is contained in:
Родитель
fc564829f6
Коммит
d8ae3d962c
|
@ -8,6 +8,7 @@ package cancellable
|
|||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/engine-api/client/transport"
|
||||
|
||||
|
@ -82,7 +83,7 @@ func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.
|
|||
// The response's Body is closed.
|
||||
}
|
||||
}()
|
||||
resp.Body = ¬ifyingReader{resp.Body, c}
|
||||
resp.Body = ¬ifyingReader{ReadCloser: resp.Body, notify: c}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
@ -91,23 +92,24 @@ func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.
|
|||
// Close is called or a Read fails on the underlying ReadCloser.
|
||||
type notifyingReader struct {
|
||||
io.ReadCloser
|
||||
notify chan<- struct{}
|
||||
notify chan<- struct{}
|
||||
notifyOnce sync.Once
|
||||
}
|
||||
|
||||
func (r *notifyingReader) Read(p []byte) (int, error) {
|
||||
n, err := r.ReadCloser.Read(p)
|
||||
if err != nil && r.notify != nil {
|
||||
close(r.notify)
|
||||
r.notify = nil
|
||||
if err != nil {
|
||||
r.notifyOnce.Do(func() {
|
||||
close(r.notify)
|
||||
})
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *notifyingReader) Close() error {
|
||||
err := r.ReadCloser.Close()
|
||||
if r.notify != nil {
|
||||
r.notifyOnce.Do(func() {
|
||||
close(r.notify)
|
||||
r.notify = nil
|
||||
}
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче