123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- package progressreader
- import (
- "bytes"
- "io"
- "sync"
- "github.com/docker/docker/vendor/src/github.com/Sirupsen/logrus"
- )
- type ProgressStatus struct {
- sync.Mutex
- c chan struct{}
- observers []io.Writer
- history bytes.Buffer
- }
- func NewProgressStatus() *ProgressStatus {
- return &ProgressStatus{
- c: make(chan struct{}),
- observers: []io.Writer{},
- }
- }
- func (ps *ProgressStatus) Write(p []byte) (n int, err error) {
- ps.Lock()
- defer ps.Unlock()
- ps.history.Write(p)
- for _, w := range ps.observers {
- // copy paste from MultiWriter, replaced return with continue
- n, err = w.Write(p)
- if err != nil {
- continue
- }
- if n != len(p) {
- err = io.ErrShortWrite
- continue
- }
- }
- return len(p), nil
- }
- func (ps *ProgressStatus) AddObserver(w io.Writer) {
- ps.Lock()
- defer ps.Unlock()
- w.Write(ps.history.Bytes())
- ps.observers = append(ps.observers, w)
- }
- func (ps *ProgressStatus) Done() {
- ps.Lock()
- close(ps.c)
- ps.history.Reset()
- ps.Unlock()
- }
- func (ps *ProgressStatus) Wait(w io.Writer, msg []byte) error {
- ps.Lock()
- channel := ps.c
- ps.Unlock()
- if channel == nil {
- // defensive
- logrus.Debugf("Channel is nil ")
- }
- if w != nil {
- w.Write(msg)
- ps.AddObserver(w)
- }
- <-channel
- return nil
- }
|