|
@@ -0,0 +1,66 @@
|
|
|
+//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()
|
|
|
+}
|