Skip to content

Commit eec997d

Browse files
typelesslafriks
authored andcommitted
Fix data race (#8204)
* Fix data race * Fix data race in modules/log * Make the scope of lock finner-grained * Use syc.Map * Fix missing change in the test * Do not export LoggerMap
1 parent a629904 commit eec997d

File tree

3 files changed

+57
-20
lines changed

3 files changed

+57
-20
lines changed

integrations/testlogger.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"runtime"
1212
"strings"
13+
"sync"
1314
"testing"
1415

1516
"code.gitea.io/gitea/modules/log"
@@ -25,11 +26,21 @@ type TestLogger struct {
2526
var writerCloser = &testLoggerWriterCloser{}
2627

2728
type testLoggerWriterCloser struct {
29+
sync.RWMutex
2830
t testing.TB
2931
}
3032

33+
func (w *testLoggerWriterCloser) setT(t *testing.TB) {
34+
w.Lock()
35+
w.t = *t
36+
w.Unlock()
37+
}
38+
3139
func (w *testLoggerWriterCloser) Write(p []byte) (int, error) {
32-
if w.t != nil {
40+
w.RLock()
41+
t := w.t
42+
w.RUnlock()
43+
if t != nil {
3344
if len(p) > 0 && p[len(p)-1] == '\n' {
3445
p = p[:len(p)-1]
3546
}
@@ -54,7 +65,7 @@ func (w *testLoggerWriterCloser) Write(p []byte) (int, error) {
5465
}
5566
}()
5667

57-
w.t.Log(string(p))
68+
t.Log(string(p))
5869
return len(p), nil
5970
}
6071
return len(p), nil
@@ -77,7 +88,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) {
7788
} else {
7889
fmt.Fprintf(os.Stdout, "=== %s (%s:%d)\n", t.Name(), strings.TrimPrefix(filename, prefix), line)
7990
}
80-
writerCloser.t = t
91+
writerCloser.setT(&t)
8192
}
8293

8394
// Printf takes a format and args and prints the string to os.Stdout

modules/log/log.go

+42-16
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,35 @@ import (
88
"os"
99
"runtime"
1010
"strings"
11+
"sync"
1112
)
1213

14+
type loggerMap struct {
15+
sync.Map
16+
}
17+
18+
func (m *loggerMap) Load(k string) (*Logger, bool) {
19+
v, ok := m.Map.Load(k)
20+
if !ok {
21+
return nil, false
22+
}
23+
l, ok := v.(*Logger)
24+
return l, ok
25+
}
26+
27+
func (m *loggerMap) Store(k string, v *Logger) {
28+
m.Map.Store(k, v)
29+
}
30+
31+
func (m *loggerMap) Delete(k string) {
32+
m.Map.Delete(k)
33+
}
34+
1335
var (
1436
// DEFAULT is the name of the default logger
1537
DEFAULT = "default"
1638
// NamedLoggers map of named loggers
17-
NamedLoggers = make(map[string]*Logger)
39+
NamedLoggers loggerMap
1840
prefix string
1941
)
2042

@@ -25,33 +47,33 @@ func NewLogger(bufLen int64, name, provider, config string) *Logger {
2547
CriticalWithSkip(1, "Unable to create default logger: %v", err)
2648
panic(err)
2749
}
28-
return NamedLoggers[DEFAULT]
50+
l, _ := NamedLoggers.Load(DEFAULT)
51+
return l
2952
}
3053

3154
// NewNamedLogger creates a new named logger for a given configuration
3255
func NewNamedLogger(name string, bufLen int64, subname, provider, config string) error {
33-
logger, ok := NamedLoggers[name]
56+
logger, ok := NamedLoggers.Load(name)
3457
if !ok {
3558
logger = newLogger(name, bufLen)
36-
37-
NamedLoggers[name] = logger
59+
NamedLoggers.Store(name, logger)
3860
}
3961

4062
return logger.SetLogger(subname, provider, config)
4163
}
4264

4365
// DelNamedLogger closes and deletes the named logger
4466
func DelNamedLogger(name string) {
45-
l, ok := NamedLoggers[name]
67+
l, ok := NamedLoggers.Load(name)
4668
if ok {
47-
delete(NamedLoggers, name)
69+
NamedLoggers.Delete(name)
4870
l.Close()
4971
}
5072
}
5173

5274
// DelLogger removes the named sublogger from the default logger
5375
func DelLogger(name string) error {
54-
logger := NamedLoggers[DEFAULT]
76+
logger, _ := NamedLoggers.Load(DEFAULT)
5577
found, err := logger.DelLogger(name)
5678
if !found {
5779
Trace("Log %s not found, no need to delete", name)
@@ -61,21 +83,24 @@ func DelLogger(name string) error {
6183

6284
// GetLogger returns either a named logger or the default logger
6385
func GetLogger(name string) *Logger {
64-
logger, ok := NamedLoggers[name]
86+
logger, ok := NamedLoggers.Load(name)
6587
if ok {
6688
return logger
6789
}
68-
return NamedLoggers[DEFAULT]
90+
logger, _ = NamedLoggers.Load(DEFAULT)
91+
return logger
6992
}
7093

7194
// GetLevel returns the minimum logger level
7295
func GetLevel() Level {
73-
return NamedLoggers[DEFAULT].GetLevel()
96+
l, _ := NamedLoggers.Load(DEFAULT)
97+
return l.GetLevel()
7498
}
7599

76100
// GetStacktraceLevel returns the minimum logger level
77101
func GetStacktraceLevel() Level {
78-
return NamedLoggers[DEFAULT].GetStacktraceLevel()
102+
l, _ := NamedLoggers.Load(DEFAULT)
103+
return l.GetStacktraceLevel()
79104
}
80105

81106
// Trace records trace log
@@ -169,18 +194,18 @@ func IsFatal() bool {
169194

170195
// Close closes all the loggers
171196
func Close() {
172-
l, ok := NamedLoggers[DEFAULT]
197+
l, ok := NamedLoggers.Load(DEFAULT)
173198
if !ok {
174199
return
175200
}
176-
delete(NamedLoggers, DEFAULT)
201+
NamedLoggers.Delete(DEFAULT)
177202
l.Close()
178203
}
179204

180205
// Log a message with defined skip and at logging level
181206
// A skip of 0 refers to the caller of this command
182207
func Log(skip int, level Level, format string, v ...interface{}) {
183-
l, ok := NamedLoggers[DEFAULT]
208+
l, ok := NamedLoggers.Load(DEFAULT)
184209
if ok {
185210
l.Log(skip+1, level, format, v...)
186211
}
@@ -195,7 +220,8 @@ type LoggerAsWriter struct {
195220
// NewLoggerAsWriter creates a Writer representation of the logger with setable log level
196221
func NewLoggerAsWriter(level string, ourLoggers ...*Logger) *LoggerAsWriter {
197222
if len(ourLoggers) == 0 {
198-
ourLoggers = []*Logger{NamedLoggers[DEFAULT]}
223+
l, _ := NamedLoggers.Load(DEFAULT)
224+
ourLoggers = []*Logger{l}
199225
}
200226
l := &LoggerAsWriter{
201227
ourLoggers: ourLoggers,

modules/log/log_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func TestNewNamedLogger(t *testing.T) {
143143
level := INFO
144144
err := NewNamedLogger("test", 0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String()))
145145
assert.NoError(t, err)
146-
logger := NamedLoggers["test"]
146+
logger, _ := NamedLoggers.Load("test")
147147
assert.Equal(t, level, logger.GetLevel())
148148

149149
written, closed := baseConsoleTest(t, logger)

0 commit comments

Comments
 (0)