From e5789770b17d4e858981879fd72e13ef49cc7816 Mon Sep 17 00:00:00 2001 From: Wade Simmons Date: Tue, 9 May 2023 11:51:02 -0400 Subject: [PATCH] keep track of what file/line the locks were grabbed on --- mutex_debug.go | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/mutex_debug.go b/mutex_debug.go index 60aeb3f..3210b1e 100644 --- a/mutex_debug.go +++ b/mutex_debug.go @@ -5,12 +5,13 @@ package nebula import ( "fmt" + "runtime" "sync" "github.com/timandy/routine" ) -var threadLocal routine.ThreadLocal = routine.NewThreadLocalWithInitial(func() any { return map[mutexKey]bool{} }) +var threadLocal routine.ThreadLocal = routine.NewThreadLocalWithInitial(func() any { return map[mutexKey]mutexValue{} }) type mutexKey struct { Type string @@ -18,6 +19,11 @@ type mutexKey struct { ID uint32 } +type mutexValue struct { + file string + line int +} + type syncRWMutex struct { sync.RWMutex mutexKey @@ -29,50 +35,54 @@ func newSyncRWMutex(key mutexKey) syncRWMutex { } } -func checkMutex(state map[mutexKey]bool, add mutexKey) { +func checkMutex(state map[mutexKey]mutexValue, add mutexKey) { switch add.Type { case "hostinfo": // Check for any other hostinfo keys: - for k, v := range state { - if k.Type == "hostinfo" && v { + for k := range state { + if k.Type == "hostinfo" { panic(fmt.Errorf("grabbing hostinfo lock and already have a hostinfo lock: state=%v add=%v", state, add)) } } - if state[mutexKey{Type: "hostmap", SubType: "main"}] { + if _, ok := state[mutexKey{Type: "hostmap", SubType: "main"}]; ok { panic(fmt.Errorf("grabbing hostinfo lock and already have hostmap-main: state=%v add=%v", state, add)) } - if state[mutexKey{Type: "hostmap", SubType: "pending"}] { + if _, ok := state[mutexKey{Type: "hostmap", SubType: "pending"}]; ok { panic(fmt.Errorf("grabbing hostinfo lock and already have hostmap-pending: state=%v add=%v", state, add)) } case "hostmap-pending": - if state[mutexKey{Type: "hostmap", SubType: "main"}] { + if _, ok := state[mutexKey{Type: "hostmap", SubType: "main"}]; ok { panic(fmt.Errorf("grabbing hostmap-pending lock and already have hostmap-main: state=%v add=%v", state, add)) } } } func (s *syncRWMutex) Lock() { - m := threadLocal.Get().(map[mutexKey]bool) + m := threadLocal.Get().(map[mutexKey]mutexValue) checkMutex(m, s.mutexKey) - m[s.mutexKey] = true + v := mutexValue{} + _, v.file, v.line, _ = runtime.Caller(1) + m[s.mutexKey] = v s.RWMutex.Lock() } func (s *syncRWMutex) Unlock() { - m := threadLocal.Get().(map[mutexKey]bool) + m := threadLocal.Get().(map[mutexKey]mutexValue) delete(m, s.mutexKey) s.RWMutex.Unlock() } func (s *syncRWMutex) RLock() { - m := threadLocal.Get().(map[mutexKey]bool) + m := threadLocal.Get().(map[mutexKey]mutexValue) checkMutex(m, s.mutexKey) - m[s.mutexKey] = true + v := mutexValue{} + _, v.file, v.line, _ = runtime.Caller(1) + m[s.mutexKey] = v s.RWMutex.RLock() } func (s *syncRWMutex) RUnlock() { - m := threadLocal.Get().(map[mutexKey]bool) + m := threadLocal.Get().(map[mutexKey]mutexValue) delete(m, s.mutexKey) s.RWMutex.RUnlock() }