| ... | ... |
@@ -213,15 +213,21 @@ func (r *bufReader) Close() error {
|
| 213 | 213 |
} |
| 214 | 214 |
|
| 215 | 215 |
type writeBroadcaster struct {
|
| 216 |
+ mu sync.Mutex |
|
| 216 | 217 |
writers *list.List |
| 217 | 218 |
} |
| 218 | 219 |
|
| 219 | 220 |
func (w *writeBroadcaster) AddWriter(writer io.WriteCloser) {
|
| 221 |
+ w.mu.Lock() |
|
| 220 | 222 |
w.writers.PushBack(writer) |
| 223 |
+ w.mu.Unlock() |
|
| 221 | 224 |
} |
| 222 | 225 |
|
| 223 | 226 |
// FIXME: Is that function used? |
| 227 |
+// FIXME: This relies on the concrete writer type used having equality operator |
|
| 224 | 228 |
func (w *writeBroadcaster) RemoveWriter(writer io.WriteCloser) {
|
| 229 |
+ w.mu.Lock() |
|
| 230 |
+ defer w.mu.Unlock() |
|
| 225 | 231 |
for e := w.writers.Front(); e != nil; e = e.Next() {
|
| 226 | 232 |
v := e.Value.(io.Writer) |
| 227 | 233 |
if v == writer {
|
| ... | ... |
@@ -232,6 +238,8 @@ func (w *writeBroadcaster) RemoveWriter(writer io.WriteCloser) {
|
| 232 | 232 |
} |
| 233 | 233 |
|
| 234 | 234 |
func (w *writeBroadcaster) Write(p []byte) (n int, err error) {
|
| 235 |
+ w.mu.Lock() |
|
| 236 |
+ defer w.mu.Unlock() |
|
| 235 | 237 |
failed := []*list.Element{}
|
| 236 | 238 |
for e := w.writers.Front(); e != nil; e = e.Next() {
|
| 237 | 239 |
writer := e.Value.(io.Writer) |
| ... | ... |
@@ -249,6 +257,8 @@ func (w *writeBroadcaster) Write(p []byte) (n int, err error) {
|
| 249 | 249 |
} |
| 250 | 250 |
|
| 251 | 251 |
func (w *writeBroadcaster) Close() error {
|
| 252 |
+ w.mu.Lock() |
|
| 253 |
+ defer w.mu.Unlock() |
|
| 252 | 254 |
for e := w.writers.Front(); e != nil; e = e.Next() {
|
| 253 | 255 |
writer := e.Value.(io.WriteCloser) |
| 254 | 256 |
writer.Close() |
| ... | ... |
@@ -258,5 +268,5 @@ func (w *writeBroadcaster) Close() error {
|
| 258 | 258 |
} |
| 259 | 259 |
|
| 260 | 260 |
func newWriteBroadcaster() *writeBroadcaster {
|
| 261 |
- return &writeBroadcaster{list.New()}
|
|
| 261 |
+ return &writeBroadcaster{writers: list.New()}
|
|
| 262 | 262 |
} |
| ... | ... |
@@ -124,3 +124,25 @@ func TestWriteBroadcaster(t *testing.T) {
|
| 124 | 124 |
|
| 125 | 125 |
writer.Close() |
| 126 | 126 |
} |
| 127 |
+ |
|
| 128 |
+type devNullCloser int |
|
| 129 |
+ |
|
| 130 |
+func (d devNullCloser) Close() error {
|
|
| 131 |
+ return nil |
|
| 132 |
+} |
|
| 133 |
+ |
|
| 134 |
+func (d devNullCloser) Write(buf []byte) (int, error) {
|
|
| 135 |
+ return len(buf), nil |
|
| 136 |
+} |
|
| 137 |
+ |
|
| 138 |
+// This test checks for races. It is only useful when run with the race detector. |
|
| 139 |
+func TestRaceWriteBroadcaster(t *testing.T) {
|
|
| 140 |
+ writer := newWriteBroadcaster() |
|
| 141 |
+ c := make(chan bool) |
|
| 142 |
+ go func() {
|
|
| 143 |
+ writer.AddWriter(devNullCloser(0)) |
|
| 144 |
+ c <- true |
|
| 145 |
+ }() |
|
| 146 |
+ writer.Write([]byte("hello"))
|
|
| 147 |
+ <-c |
|
| 148 |
+} |