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