|
1 | | -package log |
| 1 | +package log |
2 | 2 |
|
3 | 3 | import ( |
4 | 4 | "io" |
@@ -36,24 +36,59 @@ func (l *SwapLogger) Swap(logger Logger) { |
36 | 36 | l.logger.Store(loggerStruct{logger}) |
37 | 37 | } |
38 | 38 |
|
39 | | -// SyncWriter synchronizes concurrent writes to an io.Writer. |
40 | | -type SyncWriter struct { |
41 | | - mu sync.Mutex |
42 | | - w io.Writer |
| 39 | +// NewSyncWriter returns a new writer that is safe for concurrent use by |
| 40 | +// multiple goroutines. Writes to the returned writer are passed on to w. If |
| 41 | +// another write is already in progress, the calling goroutine blocks until |
| 42 | +// the writer is available. |
| 43 | +// |
| 44 | +// If w implements the following interface, so does the returned writer. |
| 45 | +// |
| 46 | +// interface { |
| 47 | +// Fd() uintptr |
| 48 | +// } |
| 49 | +func NewSyncWriter(w io.Writer) io.Writer { |
| 50 | + switch w := w.(type) { |
| 51 | + case fdWriter: |
| 52 | + return &fdSyncWriter{fdWriter: w} |
| 53 | + default: |
| 54 | + return &syncWriter{Writer: w} |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +// syncWriter synchronizes concurrent writes to an io.Writer. |
| 59 | +type syncWriter struct { |
| 60 | + sync.Mutex |
| 61 | + io.Writer |
| 62 | +} |
| 63 | + |
| 64 | +// Write writes p to the underlying io.Writer. If another write is already in |
| 65 | +// progress, the calling goroutine blocks until the syncWriter is available. |
| 66 | +func (w *syncWriter) Write(p []byte) (n int, err error) { |
| 67 | + w.Lock() |
| 68 | + n, err = w.Writer.Write(p) |
| 69 | + w.Unlock() |
| 70 | + return n, err |
| 71 | +} |
| 72 | + |
| 73 | +// fdWriter is an io.Writer that also has an Fd method. The most common |
| 74 | +// example of an fdWriter is an *os.File. |
| 75 | +type fdWriter interface { |
| 76 | + io.Writer |
| 77 | + Fd() uintptr |
43 | 78 | } |
44 | 79 |
|
45 | | -// NewSyncWriter returns a new SyncWriter. The returned writer is safe for |
46 | | -// concurrent use by multiple goroutines. |
47 | | -funcNewSyncWriter(w io.Writer) *SyncWriter { |
48 | | - return&SyncWriter{w: w} |
| 80 | +// fdSyncWriter synchronizes concurrent writes to an fdWriter. |
| 81 | +typefdSyncWriterstruct { |
| 82 | + sync.Mutex |
| 83 | + fdWriter |
49 | 84 | } |
50 | 85 |
|
51 | 86 | // Write writes p to the underlying io.Writer. If another write is already in |
52 | | -// progress, the calling goroutine blocks until the SyncWriter is available. |
53 | | -func (w *SyncWriter) Write(p []byte) (n int, err error) { |
54 | | - w.mu.Lock() |
55 | | - n, err = w.w.Write(p) |
56 | | - w.mu.Unlock() |
| 87 | +// progress, the calling goroutine blocks until the fdSyncWriter is available. |
| 88 | +func (w *fdSyncWriter) Write(p []byte) (n int, err error) { |
| 89 | + w.Lock() |
| 90 | + n, err = w.fdWriter.Write(p) |
| 91 | + w.Unlock() |
57 | 92 | return n, err |
58 | 93 | } |
59 | 94 |
|
|
0 commit comments