mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Swapped a map for a list in writeBroadcaster.
This commit is contained in:
parent
0bdfcfaa33
commit
75ba07cb3a
1 changed files with 9 additions and 24 deletions
33
utils.go
33
utils.go
|
@ -2,7 +2,6 @@ package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"container/list"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/rcli"
|
"github.com/dotcloud/docker/rcli"
|
||||||
|
@ -214,12 +213,12 @@ func (r *bufReader) Close() error {
|
||||||
|
|
||||||
type writeBroadcaster struct {
|
type writeBroadcaster struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
writers *list.List
|
writers map[io.WriteCloser]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *writeBroadcaster) AddWriter(writer io.WriteCloser) {
|
func (w *writeBroadcaster) AddWriter(writer io.WriteCloser) {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
w.writers.PushBack(writer)
|
w.writers[writer] = struct{}{}
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,46 +226,32 @@ func (w *writeBroadcaster) AddWriter(writer io.WriteCloser) {
|
||||||
// FIXME: This relies on the concrete writer type used having equality operator
|
// FIXME: This relies on the concrete writer type used having equality operator
|
||||||
func (w *writeBroadcaster) RemoveWriter(writer io.WriteCloser) {
|
func (w *writeBroadcaster) RemoveWriter(writer io.WriteCloser) {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
delete(w.writers, writer)
|
||||||
for e := w.writers.Front(); e != nil; e = e.Next() {
|
w.mu.Unlock()
|
||||||
v := e.Value.(io.Writer)
|
|
||||||
if v == writer {
|
|
||||||
w.writers.Remove(e)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *writeBroadcaster) Write(p []byte) (n int, err error) {
|
func (w *writeBroadcaster) Write(p []byte) (n int, err error) {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
failed := []*list.Element{}
|
for writer := range w.writers {
|
||||||
for e := w.writers.Front(); e != nil; e = e.Next() {
|
|
||||||
writer := e.Value.(io.Writer)
|
|
||||||
if n, err := writer.Write(p); err != nil || n != len(p) {
|
if n, err := writer.Write(p); err != nil || n != len(p) {
|
||||||
// On error, evict the writer
|
// On error, evict the writer
|
||||||
failed = append(failed, e)
|
delete(w.writers, writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We cannot remove while iterating, so it has to be done in
|
|
||||||
// a separate step
|
|
||||||
for _, e := range failed {
|
|
||||||
w.writers.Remove(e)
|
|
||||||
}
|
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *writeBroadcaster) Close() error {
|
func (w *writeBroadcaster) Close() error {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
for e := w.writers.Front(); e != nil; e = e.Next() {
|
for writer := range w.writers {
|
||||||
writer := e.Value.(io.WriteCloser)
|
|
||||||
writer.Close()
|
writer.Close()
|
||||||
}
|
}
|
||||||
w.writers.Init()
|
w.writers = make(map[io.WriteCloser]struct{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWriteBroadcaster() *writeBroadcaster {
|
func newWriteBroadcaster() *writeBroadcaster {
|
||||||
return &writeBroadcaster{writers: list.New()}
|
return &writeBroadcaster{writers: make(map[io.WriteCloser]struct{})}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue