mirror of
https://github.com/slackhq/nebula.git
synced 2024-09-20 14:56:12 +08:00
e6eeef785e
experimental test to see if we can have a test mode that verifies mutexes lock in the order we want, while having no hit on production performance. Since this uses a build tag, it should all compile out during the build process and be a no-op unless the tag is set.
67 lines
1.3 KiB
Go
67 lines
1.3 KiB
Go
//go:build mutex_debug
|
|
// +build mutex_debug
|
|
|
|
package nebula
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/timandy/routine"
|
|
)
|
|
|
|
var threadLocal routine.ThreadLocal = routine.NewThreadLocalWithInitial(func() any { return map[string]bool{} })
|
|
|
|
type syncRWMutex struct {
|
|
sync.RWMutex
|
|
mutexType string
|
|
}
|
|
|
|
func newSyncRWMutex(t ...string) syncRWMutex {
|
|
return syncRWMutex{
|
|
mutexType: strings.Join(t, "-"),
|
|
}
|
|
}
|
|
|
|
func checkMutex(state map[string]bool, add string) {
|
|
if add == "hostinfo" {
|
|
if state["hostmap-main"] {
|
|
panic("grabbing hostinfo lock and already have hostmap-main")
|
|
}
|
|
if state["hostmap-pending"] {
|
|
panic("grabbing hostinfo lock and already have hostmap-pending")
|
|
}
|
|
}
|
|
if add == "hostmap-pending" {
|
|
if state["hostmap-main"] {
|
|
panic("grabbing hostmap-pending lock and already have hostmap-main")
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *syncRWMutex) Lock() {
|
|
m := threadLocal.Get().(map[string]bool)
|
|
checkMutex(m, s.mutexType)
|
|
m[s.mutexType] = true
|
|
s.RWMutex.Lock()
|
|
}
|
|
|
|
func (s *syncRWMutex) Unlock() {
|
|
m := threadLocal.Get().(map[string]bool)
|
|
m[s.mutexType] = false
|
|
s.RWMutex.Unlock()
|
|
}
|
|
|
|
func (s *syncRWMutex) RLock() {
|
|
m := threadLocal.Get().(map[string]bool)
|
|
checkMutex(m, s.mutexType)
|
|
m[s.mutexType] = true
|
|
s.RWMutex.RLock()
|
|
}
|
|
|
|
func (s *syncRWMutex) RUnlock() {
|
|
m := threadLocal.Get().(map[string]bool)
|
|
m[s.mutexType] = false
|
|
s.RWMutex.RUnlock()
|
|
}
|