diff options
author | Mura Li <typeless@users.noreply.github.com> | 2017-04-03 10:22:26 +0800 |
---|---|---|
committer | Bo-Yi Wu <appleboy.tw@gmail.com> | 2017-04-03 10:22:26 +0800 |
commit | 93c25c9a35141a1bb52966c5256ad7020e82ab79 (patch) | |
tree | 3032d01b5259ba2654b01a7a8aaf21d32247fd18 /modules | |
parent | 5d6b71fdbb8bf28dd18714b2b168d41e3a673ab8 (diff) | |
download | gitea-93c25c9a35141a1bb52966c5256ad7020e82ab79.tar.gz gitea-93c25c9a35141a1bb52966c5256ad7020e82ab79.zip |
Fix races in the log module by using syncmap (#1421)
Diffstat (limited to 'modules')
-rw-r--r-- | modules/log/log.go | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/modules/log/log.go b/modules/log/log.go index 0b76002230..24ac3f652f 100644 --- a/modules/log/log.go +++ b/modules/log/log.go @@ -12,6 +12,8 @@ import ( "runtime" "strings" "sync" + + "golang.org/x/sync/syncmap" ) var ( @@ -42,10 +44,11 @@ func NewLogger(bufLen int64, mode, config string) { // DelLogger removes loggers that are for the given mode func DelLogger(mode string) error { for _, l := range loggers { - if _, ok := l.outputs[mode]; ok { + if _, ok := l.outputs.Load(mode); ok { return l.DelLogger(mode) } } + Trace("Log adapter %s not found, no need to delete", mode) return nil } @@ -177,16 +180,15 @@ type Logger struct { lock sync.Mutex level int msg chan *logMsg - outputs map[string]LoggerInterface + outputs syncmap.Map quit chan bool } // newLogger initializes and returns a new logger. func newLogger(buffer int64) *Logger { l := &Logger{ - msg: make(chan *logMsg, buffer), - outputs: make(map[string]LoggerInterface), - quit: make(chan bool), + msg: make(chan *logMsg, buffer), + quit: make(chan bool), } go l.StartLogger() return l @@ -194,14 +196,12 @@ func newLogger(buffer int64) *Logger { // SetLogger sets new logger instance with given logger adapter and config. func (l *Logger) SetLogger(adapter string, config string) error { - l.lock.Lock() - defer l.lock.Unlock() if log, ok := adapters[adapter]; ok { lg := log() if err := lg.Init(config); err != nil { return err } - l.outputs[adapter] = lg + l.outputs.Store(adapter, lg) l.adapter = adapter } else { panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)") @@ -211,11 +211,9 @@ func (l *Logger) SetLogger(adapter string, config string) error { // DelLogger removes a logger adapter instance. func (l *Logger) DelLogger(adapter string) error { - l.lock.Lock() - defer l.lock.Unlock() - if lg, ok := l.outputs[adapter]; ok { - lg.Destroy() - delete(l.outputs, adapter) + if lg, ok := l.outputs.Load(adapter); ok { + lg.(LoggerInterface).Destroy() + l.outputs.Delete(adapter) } else { panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)") } @@ -264,11 +262,12 @@ func (l *Logger) StartLogger() { for { select { case bm := <-l.msg: - for _, l := range l.outputs { - if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil { + l.outputs.Range(func(k, v interface{}) bool { + if err := v.(LoggerInterface).WriteMsg(bm.msg, bm.skip, bm.level); err != nil { fmt.Println("ERROR, unable to WriteMsg:", err) } - } + return true + }) case <-l.quit: return } @@ -277,9 +276,10 @@ func (l *Logger) StartLogger() { // Flush flushes all chan data. func (l *Logger) Flush() { - for _, l := range l.outputs { - l.Flush() - } + l.outputs.Range(func(k, v interface{}) bool { + v.(LoggerInterface).Flush() + return true + }) } // Close closes logger, flush all chan data and destroy all adapter instances. @@ -288,19 +288,21 @@ func (l *Logger) Close() { for { if len(l.msg) > 0 { bm := <-l.msg - for _, l := range l.outputs { - if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil { + l.outputs.Range(func(k, v interface{}) bool { + if err := v.(LoggerInterface).WriteMsg(bm.msg, bm.skip, bm.level); err != nil { fmt.Println("ERROR, unable to WriteMsg:", err) } - } + return true + }) } else { break } } - for _, l := range l.outputs { - l.Flush() - l.Destroy() - } + l.outputs.Range(func(k, v interface{}) bool { + v.(LoggerInterface).Flush() + v.(LoggerInterface).Destroy() + return true + }) } // Trace records trace log |