mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-12 14:03:58 +01:00
keep track of what file/line the locks were grabbed on
This commit is contained in:
parent
a83f0ca470
commit
e5789770b1
@ -5,12 +5,13 @@ package nebula
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/timandy/routine"
|
"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 mutexKey struct {
|
||||||
Type string
|
Type string
|
||||||
@ -18,6 +19,11 @@ type mutexKey struct {
|
|||||||
ID uint32
|
ID uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mutexValue struct {
|
||||||
|
file string
|
||||||
|
line int
|
||||||
|
}
|
||||||
|
|
||||||
type syncRWMutex struct {
|
type syncRWMutex struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
mutexKey
|
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 {
|
switch add.Type {
|
||||||
case "hostinfo":
|
case "hostinfo":
|
||||||
// Check for any other hostinfo keys:
|
// Check for any other hostinfo keys:
|
||||||
for k, v := range state {
|
for k := range state {
|
||||||
if k.Type == "hostinfo" && v {
|
if k.Type == "hostinfo" {
|
||||||
panic(fmt.Errorf("grabbing hostinfo lock and already have a hostinfo lock: state=%v add=%v", state, add))
|
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))
|
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))
|
panic(fmt.Errorf("grabbing hostinfo lock and already have hostmap-pending: state=%v add=%v", state, add))
|
||||||
}
|
}
|
||||||
case "hostmap-pending":
|
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))
|
panic(fmt.Errorf("grabbing hostmap-pending lock and already have hostmap-main: state=%v add=%v", state, add))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncRWMutex) Lock() {
|
func (s *syncRWMutex) Lock() {
|
||||||
m := threadLocal.Get().(map[mutexKey]bool)
|
m := threadLocal.Get().(map[mutexKey]mutexValue)
|
||||||
checkMutex(m, s.mutexKey)
|
checkMutex(m, s.mutexKey)
|
||||||
m[s.mutexKey] = true
|
v := mutexValue{}
|
||||||
|
_, v.file, v.line, _ = runtime.Caller(1)
|
||||||
|
m[s.mutexKey] = v
|
||||||
s.RWMutex.Lock()
|
s.RWMutex.Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncRWMutex) Unlock() {
|
func (s *syncRWMutex) Unlock() {
|
||||||
m := threadLocal.Get().(map[mutexKey]bool)
|
m := threadLocal.Get().(map[mutexKey]mutexValue)
|
||||||
delete(m, s.mutexKey)
|
delete(m, s.mutexKey)
|
||||||
s.RWMutex.Unlock()
|
s.RWMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncRWMutex) RLock() {
|
func (s *syncRWMutex) RLock() {
|
||||||
m := threadLocal.Get().(map[mutexKey]bool)
|
m := threadLocal.Get().(map[mutexKey]mutexValue)
|
||||||
checkMutex(m, s.mutexKey)
|
checkMutex(m, s.mutexKey)
|
||||||
m[s.mutexKey] = true
|
v := mutexValue{}
|
||||||
|
_, v.file, v.line, _ = runtime.Caller(1)
|
||||||
|
m[s.mutexKey] = v
|
||||||
s.RWMutex.RLock()
|
s.RWMutex.RLock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncRWMutex) RUnlock() {
|
func (s *syncRWMutex) RUnlock() {
|
||||||
m := threadLocal.Get().(map[mutexKey]bool)
|
m := threadLocal.Get().(map[mutexKey]mutexValue)
|
||||||
delete(m, s.mutexKey)
|
delete(m, s.mutexKey)
|
||||||
s.RWMutex.RUnlock()
|
s.RWMutex.RUnlock()
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user