]> 127.0.0.1 Git - part/.git/commitdiff
1
authorqydysky <qydysky@foxmail.com>
Sat, 29 Jul 2023 03:53:58 +0000 (11:53 +0800)
committerqydysky <qydysky@foxmail.com>
Sat, 29 Jul 2023 03:53:58 +0000 (11:53 +0800)
msgq/Msgq.go
sync/RWMutex.go
sync/RWMutex_test.go

index b0a1403e56fb9b6b5451341465a35776cb715ce3..0173e1aad1971c3f05e646b43a7e6e21063320a5 100644 (file)
@@ -61,9 +61,8 @@ func (m *Msgq) Register_front(f func(any) (disable bool)) {
 }
 
 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)
@@ -80,9 +79,8 @@ func (m *Msgq) Push(msg any) {
 }
 
 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)
@@ -111,9 +109,6 @@ func (m *Msgq) removeDisable() {
                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 {
@@ -155,9 +150,8 @@ func (m *Msgq) Push_tag(Tag string, Data any) {
                                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)
@@ -205,9 +199,8 @@ func (m *Msgq) PushLock_tag(Tag string, Data any) {
                                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)
@@ -358,9 +351,8 @@ func (m *MsgType[T]) Push_tag(Tag string, Data T) {
                                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)
@@ -408,9 +400,8 @@ func (m *MsgType[T]) PushLock_tag(Tag string, Data T) {
                                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)
index e2f2a931385920421b677c50953f71e6f97b2646..e2f0ed306a58d16d4af3662fd6a841d074b86f82 100644 (file)
@@ -92,7 +92,7 @@ func tof(to time.Duration) (inTimeCall func() (called bool)) {
 // 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 {
@@ -109,7 +109,7 @@ func (m *RWMutex) RLock(to ...time.Duration) (unlockf func()) {
        if len(to) > 1 {
                done = tof(to[1])
        }
-       return func() {
+       return func(beforeUlock ...func()) {
                if !callC.CompareAndSwap(false, true) {
                        panic("had unlock")
                }
@@ -117,6 +117,9 @@ func (m *RWMutex) RLock(to ...time.Duration) (unlockf func()) {
                        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)
@@ -126,7 +129,7 @@ func (m *RWMutex) RLock(to ...time.Duration) (unlockf func()) {
 }
 
 // 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)
@@ -136,13 +139,16 @@ func (m *RWMutex) Lock(to ...time.Duration) (unlockf func()) {
        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)
index 07644f94104a35844fe118d46987a5e0ebe4a86e..008eab67fb6c1150141c9633378130553f627cc0 100644 (file)
@@ -78,6 +78,44 @@ func Test3(t *testing.T) {
        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