Просмотр исходного кода

keep track of what file/line the locks were grabbed on

Wade Simmons 2 лет назад
Родитель
Сommit
e5789770b1
1 измененных файлов с 23 добавлено и 13 удалено
  1. 23 13
      mutex_debug.go

+ 23 - 13
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()
 }