}
func (m *Msgq) Push(msg any) {
- defer m.removeDisable()
ul := m.lock.RLock(m.to...)
- defer ul()
+ defer ul(m.removeDisable)
for el := m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
}
func (m *Msgq) PushLock(msg any) {
- defer m.removeDisable()
ul := m.lock.Lock(m.to...)
- defer ul()
+ defer ul(m.removeDisable)
for el := m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
return
}
- ul := m.lock.Lock(m.to...)
- defer ul()
-
for el := m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
if mi.disable.Load() && mi.running.Load() == 0 {
Data: Data,
})
*/
- defer m.removeDisable()
ul := m.lock.RLock(m.to...)
- defer ul()
+ defer ul(m.removeDisable)
for el := m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
Data: Data,
})
*/
- defer m.removeDisable()
ul := m.lock.Lock(m.to...)
- defer ul()
+ defer ul(m.removeDisable)
for el := m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
Data: Data,
})
*/
- defer m.m.removeDisable()
ul := m.m.lock.RLock(m.m.to...)
- defer ul()
+ defer ul(m.m.removeDisable)
for el := m.m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
Data: Data,
})
*/
- defer m.m.removeDisable()
ul := m.m.lock.Lock(m.m.to...)
- defer ul()
+ defer ul(m.m.removeDisable)
for el := m.m.funcs.Front(); el != nil; el = el.Next() {
mi := el.Value.(*msgqItem)
// to[0]: wait lock timeout to[1]: run lock timeout
//
// 不要在Rlock内设置变量,有DATA RACE风险
-func (m *RWMutex) RLock(to ...time.Duration) (unlockf func()) {
+func (m *RWMutex) RLock(to ...time.Duration) (unlockf func(beforeUlock ...func())) {
if m.read.Add(1) == 1 {
_, rlcLoop := cas(&m.rlc, ulock, rlock)
if e := rlcLoop(to...); e != nil {
if len(to) > 1 {
done = tof(to[1])
}
- return func() {
+ return func(beforeUlock ...func()) {
if !callC.CompareAndSwap(false, true) {
panic("had unlock")
}
done()
}
if m.read.Add(-1) == 0 {
+ for i := 0; i < len(beforeUlock); i++ {
+ beforeUlock[i]()
+ }
_, rlcLoop := cas(&m.rlc, rlock, ulock)
if e := rlcLoop(to...); e != nil {
panic(e)
}
// to[0]: wait lock timeout to[1]: run lock timeout
-func (m *RWMutex) Lock(to ...time.Duration) (unlockf func()) {
+func (m *RWMutex) Lock(to ...time.Duration) (unlockf func(beforeUlock ...func())) {
_, rlcLoop := cas(&m.rlc, ulock, lock)
if e := rlcLoop(to...); e != nil {
panic(e)
if len(to) > 1 {
done = tof(to[1])
}
- return func() {
+ return func(beforeUlock ...func()) {
if !callC.CompareAndSwap(false, true) {
panic("had unlock")
}
if done != nil {
done()
}
+ for i := 0; i < len(beforeUlock); i++ {
+ beforeUlock[i]()
+ }
_, rlcLoop := cas(&m.rlc, lock, ulock)
if e := rlcLoop(to...); e != nil {
panic(e)
check(&l, ulock, 0)
}
+func Test6(t *testing.T) {
+ var c = make(chan int, 2)
+ var l RWMutex
+ ul := l.RLock()
+ time.AfterFunc(time.Millisecond*500, func() {
+ ul1 := l.RLock()
+ c <- 1
+ ul1()
+ c <- 2
+ })
+ ul(func() {
+ time.Sleep(time.Second)
+ })
+ c <- 0
+ if <-c != 0 {
+ t.Fatal()
+ }
+ if <-c != 1 {
+ t.Fatal()
+ }
+}
+
+func Test7(t *testing.T) {
+ var c = make(chan int, 2)
+ var l RWMutex
+ ul := l.RLock()
+ ul1 := l.RLock()
+ ul(func() {
+ c <- 0
+ })
+ ul1(func() {
+ c <- 1
+ })
+ if <-c != 1 {
+ t.Fatal()
+ }
+}
+
// ulock rlock rlock
func Panic_Test4(t *testing.T) {
var l RWMutex