summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorMura Li <typeless@users.noreply.github.com>2017-04-03 10:22:26 +0800
committerBo-Yi Wu <appleboy.tw@gmail.com>2017-04-03 10:22:26 +0800
commit93c25c9a35141a1bb52966c5256ad7020e82ab79 (patch)
tree3032d01b5259ba2654b01a7a8aaf21d32247fd18 /modules
parent5d6b71fdbb8bf28dd18714b2b168d41e3a673ab8 (diff)
downloadgitea-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.go54
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