}
func (m *Msgq) Register(f func(any) (disable bool)) {
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
m.funcs.PushBack(f)
ul()
}
func (m *Msgq) Register_front(f func(any) (disable bool)) {
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
m.funcs.PushFront(f)
ul()
}
var removes []*list.Element
- ul := m.lock.RLock(m.to...)
+ ul := m.lock.RLock(m.to...)()
for el := m.funcs.Front(); el != nil; el = el.Next() {
if disable := el.Value.(func(any) bool)(msg); disable {
m.someNeedRemove.Add(1)
ul()
if len(removes) != 0 {
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
m.someNeedRemove.Add(-int32(len(removes)))
for i := 0; i < len(removes); i++ {
m.funcs.Remove(removes[i])
runtime.Gosched()
}
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
defer ul()
var removes []*list.Element
runtime.Gosched()
}
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
defer ul()
var removes []*list.Element
var removes []*list.Element
- ul := m.lock.RLock(m.to...)
+ ul := m.lock.RLock(m.to...)()
for el := m.funcs.Front(); el != nil; el = el.Next() {
if disable := el.Value.(func(MsgType_tag_data[T]) bool)(msg); disable {
m.someNeedRemove.Add(1)
ul()
if len(removes) != 0 {
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
m.someNeedRemove.Add(-int32(len(removes)))
for i := 0; i < len(removes); i++ {
m.funcs.Remove(removes[i])
runtime.Gosched()
}
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
defer ul()
var removes []*list.Element
}
func (m *MsgType[T]) register(f func(MsgType_tag_data[T]) (disable bool)) {
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
m.funcs.PushBack(f)
ul()
}
func (m *MsgType[T]) register_front(f func(MsgType_tag_data[T]) (disable bool)) {
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
m.funcs.PushFront(f)
ul()
}
runtime.Gosched()
}
- ul := m.lock.Lock(m.to...)
+ ul := m.lock.Lock(m.to...)()
defer ul()
var removes []*list.Element
oll atomic.Int32
}
-func (m *RWMutex) RLock(to ...time.Duration) (unrlock func()) {
- var callC atomic.Bool
- if len(to) > 0 {
- var calls []string
- for i := 1; true; i++ {
- if pc, file, line, ok := runtime.Caller(i); !ok {
- break
- } else {
- calls = append(calls, fmt.Sprintf("%s\n\t%s:%d", runtime.FuncForPC(pc).Name(), file, line))
- }
- }
- c := time.Now()
- for m.rlc.Load() < ulock || m.cul.Load() != m.oll.Load() {
- if time.Since(c) > to[0] {
- panic(fmt.Sprintf("timeout to wait lock, rlc:%d", m.rlc.Load()))
+// RLock() 必须在 lock期间操作的变量所定义的goroutime 中调用
+func (m *RWMutex) RLock(to ...time.Duration) (lockf func() (unlockf func())) {
+ lockid := m.cul.Add(1)
+ return func() (unlockf func()) {
+ var callC atomic.Bool
+ if len(to) > 0 {
+ var calls []string
+ for i := 1; true; i++ {
+ if pc, file, line, ok := runtime.Caller(i); !ok {
+ break
+ } else {
+ calls = append(calls, fmt.Sprintf("%s\n\t%s:%d", runtime.FuncForPC(pc).Name(), file, line))
+ }
}
- runtime.Gosched()
- }
- c = time.Now()
- go func() {
- for !callC.Load() {
+ c := time.Now()
+ for m.rlc.Load() < ulock {
if time.Since(c) > to[0] {
- panicS := fmt.Sprintf("timeout to run rlock %v > %v\n", time.Since(c), to[0])
- for i := 0; i < len(calls); i++ {
- panicS += fmt.Sprintf("%s\n", calls[i])
+ panic(fmt.Sprintf("timeout to wait lock, rlc:%d", m.rlc.Load()))
+ }
+ runtime.Gosched()
+ }
+ if lockid > m.oll.Load() {
+ m.oll.Store(lockid)
+ }
+ c = time.Now()
+ go func() {
+ for !callC.Load() {
+ if time.Since(c) > to[0] {
+ panicS := fmt.Sprintf("timeout to run rlock %v > %v\n", time.Since(c), to[0])
+ for i := 0; i < len(calls); i++ {
+ panicS += fmt.Sprintf("%s\n", calls[i])
+ }
+ panic(panicS)
}
- panic(panicS)
+ runtime.Gosched()
}
+ }()
+ } else {
+ for m.rlc.Load() < ulock {
+ time.Sleep(time.Millisecond)
runtime.Gosched()
}
- }()
- } else {
- for m.rlc.Load() < ulock || m.cul.Load() != m.oll.Load() {
- time.Sleep(time.Millisecond)
- runtime.Gosched()
+ if lockid > m.oll.Load() {
+ m.oll.Store(lockid)
+ }
}
- }
- m.rlc.Add(1)
- return func() {
- if !callC.CompareAndSwap(false, true) {
- panic("had unrlock")
+ m.rlc.Add(1)
+ return func() {
+ if !callC.CompareAndSwap(false, true) {
+ panic("had unrlock")
+ }
+ m.rlc.Add(-1)
}
- m.rlc.Add(-1)
}
}
-func (m *RWMutex) Lock(to ...time.Duration) (unlock func()) {
+// Lock() 必须在 lock期间操作的变量所定义的goroutime 中调用
+func (m *RWMutex) Lock(to ...time.Duration) (lockf func() (unlockf func())) {
lockid := m.cul.Add(1)
- var callC atomic.Bool
- if len(to) > 0 {
- var calls []string
- for i := 1; true; i++ {
- if pc, file, line, ok := runtime.Caller(i); !ok {
- break
- } else {
- calls = append(calls, fmt.Sprintf("%s\n\t%s:%d", runtime.FuncForPC(pc).Name(), file, line))
+ return func() (unlock func()) {
+ var callC atomic.Bool
+ if len(to) > 0 {
+ var calls []string
+ for i := 1; true; i++ {
+ if pc, file, line, ok := runtime.Caller(i); !ok {
+ break
+ } else {
+ calls = append(calls, fmt.Sprintf("%s\n\t%s:%d", runtime.FuncForPC(pc).Name(), file, line))
+ }
}
- }
- c := time.Now()
- for m.rlc.Load() > ulock {
- if time.Since(c) > to[0] {
- panic(fmt.Sprintf("timeout to wait rlock, rlc:%d", m.rlc.Load()))
+ c := time.Now()
+ for m.rlc.Load() > ulock || lockid-1 != m.oll.Load() {
+ if time.Since(c) > to[0] {
+ panic(fmt.Sprintf("timeout to wait rlock, rlc:%d", m.rlc.Load()))
+ }
+ runtime.Gosched()
}
- runtime.Gosched()
- }
- for lockid-1 != m.oll.Load() {
- if time.Since(c) > to[0] {
- panic(fmt.Sprintf("timeout to wait lock, rlc:%d", m.rlc.Load()))
+ if !m.rlc.CompareAndSwap(ulock, lock) {
+ panic(fmt.Sprintf("csa error, rlc:%d", m.rlc.Load()))
}
- runtime.Gosched()
- }
- if !m.rlc.CompareAndSwap(ulock, lock) {
- panic(fmt.Sprintf("csa error, rlc:%d", m.rlc.Load()))
- }
- c = time.Now()
- go func() {
- for !callC.Load() {
- if time.Since(c) > to[0] {
- panicS := fmt.Sprintf("timeout to run lock %v > %v\n", time.Since(c), to[0])
- for i := 0; i < len(calls); i++ {
- panicS += fmt.Sprintf("call by %s\n", calls[i])
+ c = time.Now()
+ go func() {
+ for !callC.Load() {
+ if time.Since(c) > to[0] {
+ panicS := fmt.Sprintf("timeout to run lock %v > %v\n", time.Since(c), to[0])
+ for i := 0; i < len(calls); i++ {
+ panicS += fmt.Sprintf("call by %s\n", calls[i])
+ }
+ panic(panicS)
}
- panic(panicS)
+ runtime.Gosched()
}
+ }()
+ } else {
+ for m.rlc.Load() > ulock || lockid-1 != m.oll.Load() {
+ time.Sleep(time.Millisecond)
runtime.Gosched()
}
- }()
- } else {
- for m.rlc.Load() > ulock {
- time.Sleep(time.Millisecond)
- runtime.Gosched()
- }
- for lockid-1 != m.oll.Load() {
- time.Sleep(time.Millisecond)
- runtime.Gosched()
- }
- if !m.rlc.CompareAndSwap(ulock, lock) {
- panic(fmt.Sprintf("csa error, rlc:%d", m.rlc.Load()))
- }
- }
- return func() {
- if !callC.CompareAndSwap(false, true) {
- panic("had unlock")
+ if !m.rlc.CompareAndSwap(ulock, lock) {
+ panic(fmt.Sprintf("csa error, rlc:%d", m.rlc.Load()))
+ }
}
- if !m.rlc.CompareAndSwap(lock, ulock) {
- panic("")
+ return func() {
+ if !callC.CompareAndSwap(false, true) {
+ panic("had unlock")
+ }
+ if !m.rlc.CompareAndSwap(lock, ulock) {
+ panic("")
+ }
+ m.oll.Store(lockid)
}
- m.oll.Store(lockid)
}
}