diff --git a/command/agent/gated_writer.go b/command/agent/gated_writer.go index e9417c4b097a..602f018a4da7 100644 --- a/command/agent/gated_writer.go +++ b/command/agent/gated_writer.go @@ -29,15 +29,28 @@ func (w *GatedWriter) Flush() { } func (w *GatedWriter) Write(p []byte) (n int, err error) { - w.lock.RLock() - defer w.lock.RUnlock() - - if w.flush { - return w.Writer.Write(p) - } - - p2 := make([]byte, len(p)) - copy(p2, p) - w.buf = append(w.buf, p2) - return len(p), nil + // Once we flush we no longer synchronize writers since there's + // no use of the internal buffer. This is the happy path. + w.lock.RLock() + if w.flush { + w.lock.RUnlock() + return w.Writer.Write(p) + } + w.lock.RUnlock() + + // Now take the write lock. + w.lock.Lock() + defer w.lock.Unlock() + + // Things could have changed between the locking operations, so we + // have to check one more time. + if w.flush { + return w.Writer.Write(p) + } + + // Buffer up the written data. + p2 := make([]byte, len(p)) + copy(p2, p) + w.buf = append(w.buf, p2) + return len(p), nil }