nebula/mutex_debug.go

67 lines
1.3 KiB
Go
Raw Normal View History

//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()
}