aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-07-17 15:46:00 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-07-17 15:46:00 -0700
commit607520690491ae510f3f0c5a5482d393e6d6efe7 (patch)
tree5d924ae5ba5ed4b1dc8a668eaae544a9eb7ad864
parentc705701c69a0ae18ec690cd6a34481f52c52f65b (diff)
downloadgo-607520690491ae510f3f0c5a5482d393e6d6efe7.tar.gz
go-607520690491ae510f3f0c5a5482d393e6d6efe7.zip
log: more locking
This didn't actually cause a bug, but looks wrong. There was a lock but there was more shared mutable state not guarded by it. R=golang-dev, dsymonds, r CC=golang-dev https://golang.org/cl/4760047
-rw-r--r--src/pkg/log/log.go20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/pkg/log/log.go b/src/pkg/log/log.go
index 00bce6a17d..ec097434bb 100644
--- a/src/pkg/log/log.go
+++ b/src/pkg/log/log.go
@@ -41,9 +41,9 @@ const (
// the Writer's Write method. A Logger can be used simultaneously from
// multiple goroutines; it guarantees to serialize access to the Writer.
type Logger struct {
+ mu sync.Mutex // ensures atomic writes; protects the following fields
prefix string // prefix to write at beginning of each line
flag int // properties
- mu sync.Mutex // ensures atomic writes; protects the following fields
out io.Writer // destination for output
buf bytes.Buffer // for accumulating text to write
}
@@ -134,19 +134,21 @@ func (l *Logger) formatHeader(buf *bytes.Buffer, ns int64, file string, line int
// paths it will be 2.
func (l *Logger) Output(calldepth int, s string) os.Error {
now := time.Nanoseconds() // get this early.
- // get caller info (if required) before locking - it's expensive.
var file string
var line int
+ l.mu.Lock()
+ defer l.mu.Unlock()
if l.flag&(Lshortfile|Llongfile) != 0 {
+ // release lock while getting caller info - it's expensive.
+ l.mu.Unlock()
var ok bool
_, file, line, ok = runtime.Caller(calldepth)
if !ok {
file = "???"
line = 0
}
+ l.mu.Lock()
}
- l.mu.Lock()
- defer l.mu.Unlock()
l.buf.Reset()
l.formatHeader(&l.buf, now, file, line)
l.buf.WriteString(s)
@@ -212,26 +214,36 @@ func (l *Logger) Panicln(v ...interface{}) {
// Flags returns the output flags for the logger.
func (l *Logger) Flags() int {
+ l.mu.Lock()
+ defer l.mu.Unlock()
return l.flag
}
// SetFlags sets the output flags for the logger.
func (l *Logger) SetFlags(flag int) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
l.flag = flag
}
// Prefix returns the output prefix for the logger.
func (l *Logger) Prefix() string {
+ l.mu.Lock()
+ defer l.mu.Unlock()
return l.prefix
}
// SetPrefix sets the output prefix for the logger.
func (l *Logger) SetPrefix(prefix string) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
l.prefix = prefix
}
// SetOutput sets the output destination for the standard logger.
func SetOutput(w io.Writer) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
std.out = w
}