github.com/hauerwu/docker@v1.8.0-rc1/pkg/broadcastwriter/broadcastwriter.go (about)

     1  package broadcastwriter
     2  
     3  import (
     4  	"io"
     5  	"sync"
     6  )
     7  
     8  // BroadcastWriter accumulate multiple io.WriteCloser by stream.
     9  type BroadcastWriter struct {
    10  	sync.Mutex
    11  	writers map[io.WriteCloser]struct{}
    12  }
    13  
    14  // AddWriter adds new io.WriteCloser.
    15  func (w *BroadcastWriter) AddWriter(writer io.WriteCloser) {
    16  	w.Lock()
    17  	w.writers[writer] = struct{}{}
    18  	w.Unlock()
    19  }
    20  
    21  // Write writes bytes to all writers. Failed writers will be evicted during
    22  // this call.
    23  func (w *BroadcastWriter) Write(p []byte) (n int, err error) {
    24  	w.Lock()
    25  	for sw := range w.writers {
    26  		if n, err := sw.Write(p); err != nil || n != len(p) {
    27  			// On error, evict the writer
    28  			delete(w.writers, sw)
    29  		}
    30  	}
    31  	w.Unlock()
    32  	return len(p), nil
    33  }
    34  
    35  // Clean closes and removes all writers. Last non-eol-terminated part of data
    36  // will be saved.
    37  func (w *BroadcastWriter) Clean() error {
    38  	w.Lock()
    39  	for w := range w.writers {
    40  		w.Close()
    41  	}
    42  	w.writers = make(map[io.WriteCloser]struct{})
    43  	w.Unlock()
    44  	return nil
    45  }
    46  
    47  func New() *BroadcastWriter {
    48  	return &BroadcastWriter{
    49  		writers: make(map[io.WriteCloser]struct{}),
    50  	}
    51  }