From: qydysky Date: Tue, 11 Feb 2025 19:42:42 +0000 (+0800) Subject: 1 (#24) X-Git-Tag: v0.28.20250211194255 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=cb35c6765fbadd2b476026b46c17f9dc276c76b7;p=part%2F.git 1 (#24) * 1 * 1 * 1 * 1 --- diff --git a/errors/errors.go b/errors/errors.go index fe1e39d..ab72a03 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -21,8 +21,11 @@ func (t Action) New(reason ...string) (e Error) { return } +func (t Action) Error() string { + return string(t) +} + type Error struct { - son error Reason string action Action } diff --git a/msgq/Msgq.go b/msgq/Msgq.go index d2f732a..d3c8e76 100644 --- a/msgq/Msgq.go +++ b/msgq/Msgq.go @@ -81,7 +81,7 @@ func (m *Msgq) Register_front(f func(any) (disable bool)) (cancel func()) { func (m *Msgq) Push(msg any) { ul := m.lock.RLock(m.to...) - defer ul(m.removeDisable) + defer ul(m.removeDisable(true)...) for el := m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) @@ -99,7 +99,7 @@ func (m *Msgq) Push(msg any) { func (m *Msgq) PushLock(msg any) { ul := m.lock.Lock(m.to...) - defer ul(m.removeDisable) + defer ul(m.removeDisable(false)...) for el := m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) @@ -123,15 +123,38 @@ func (m *Msgq) ClearAll() { } } -func (m *Msgq) removeDisable() { - if !m.someNeedRemove.CompareAndSwap(true, false) { - return - } - - for el := m.funcs.Front(); el != nil; el = el.Next() { - mi := el.Value.(*msgqItem) - if mi.disable.Load() && mi.running.Load() == 0 { - m.funcs.Remove(el) +func (m *Msgq) removeDisable(rlock bool) (ls []func(ulocked bool) (doUlock bool)) { + if rlock { + return []func(ulocked bool) (doUlock bool){ + func(ulocked bool) (doUlock bool) { + return m.someNeedRemove.CompareAndSwap(true, false) + }, + func(ulocked bool) (doUlock bool) { + if ulocked { + defer m.lock.Lock()() + for el := m.funcs.Front(); el != nil; el = el.Next() { + mi := el.Value.(*msgqItem) + if mi.disable.Load() && mi.running.Load() == 0 { + m.funcs.Remove(el) + } + } + } + return + }, + } + } else { + return []func(ulocked bool) (doUlock bool){ + func(ulocked bool) (doUlock bool) { + if m.someNeedRemove.CompareAndSwap(true, false) { + for el := m.funcs.Front(); el != nil; el = el.Next() { + mi := el.Value.(*msgqItem) + if mi.disable.Load() && mi.running.Load() == 0 { + m.funcs.Remove(el) + } + } + } + return + }, } } } @@ -169,7 +192,7 @@ func (m *Msgq) Push_tag(Tag string, Data any) { Data: Data, }) */ - defer m.lock.RLock(m.to...)(m.removeDisable) + defer m.lock.RLock(m.to...)(m.removeDisable(true)...) for el := m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) @@ -218,7 +241,7 @@ func (m *Msgq) PushLock_tag(Tag string, Data any) { }) */ ul := m.lock.Lock(m.to...) - defer ul(m.removeDisable) + defer ul(m.removeDisable(false)...) for el := m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) @@ -376,7 +399,7 @@ func (m *MsgType[T]) Push_tag(Tag string, Data T) { }) */ ul := m.m.lock.RLock(m.m.to...) - defer ul(m.m.removeDisable) + defer ul(m.m.removeDisable(true)...) for el := m.m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) @@ -425,7 +448,7 @@ func (m *MsgType[T]) PushLock_tag(Tag string, Data T) { }) */ ul := m.m.lock.Lock(m.m.to...) - defer ul(m.m.removeDisable) + defer ul(m.m.removeDisable(false)...) for el := m.m.funcs.Front(); el != nil; el = el.Next() { mi := el.Value.(*msgqItem) diff --git a/sync/RWMutex.go b/sync/RWMutex.go index 9f787c2..2794493 100644 --- a/sync/RWMutex.go +++ b/sync/RWMutex.go @@ -86,42 +86,60 @@ func (m *RWMutex) tof(to time.Duration, e error) (inTimeCall func() (called bool // to[1]: wait ulock timeout // // 不要在Rlock内设置变量,有DATA RACE风险 -func (m *RWMutex) RLock(to ...time.Duration) (unlockf func(beforeUlock ...func())) { +func (m *RWMutex) RLock(to ...time.Duration) (unlockf func(ulockfs ...func(ulocked bool) (doUlock bool))) { if len(to) > 0 { defer m.tof(to[0], ErrTimeoutToLock)() } m.rlc.RLock() - return func(beforeUlock ...func()) { + return func(ulockfs ...func(ulocked bool) (doUlock bool)) { + inTimeCall := func() (called bool) { return true } if len(to) > 1 { - defer m.tof(to[1], ErrTimeoutToULock)() + inTimeCall = m.tof(to[1], ErrTimeoutToULock) } - for i := 0; i < len(beforeUlock); i++ { - beforeUlock[i]() + ul := false + for i := 0; i < len(ulockfs); i++ { + if ulockfs[i](ul) && !ul { + m.rlc.RUnlock() + inTimeCall() + ul = true + } + } + if !ul { + m.rlc.RUnlock() + inTimeCall() } - m.rlc.RUnlock() } } // to[0]: wait lock timeout // // to[1]: wait ulock timeout -func (m *RWMutex) Lock(to ...time.Duration) (unlockf func(beforeUlock ...func())) { +func (m *RWMutex) Lock(to ...time.Duration) (unlockf func(ulockfs ...func(ulocked bool) (doUlock bool))) { if len(to) > 0 { defer m.tof(to[0], ErrTimeoutToLock)() } m.rlc.Lock() - return func(beforeUlock ...func()) { + return func(ulockfs ...func(ulocked bool) (doUlock bool)) { + inTimeCall := func() (called bool) { return true } if len(to) > 1 { - defer m.tof(to[1], ErrTimeoutToULock)() + inTimeCall = m.tof(to[1], ErrTimeoutToULock) + } + ul := false + for i := 0; i < len(ulockfs); i++ { + if ulockfs[i](ul) && !ul { + m.rlc.Unlock() + inTimeCall() + ul = true + } } - for i := 0; i < len(beforeUlock); i++ { - beforeUlock[i]() + if !ul { + m.rlc.Unlock() + inTimeCall() } - m.rlc.Unlock() } } diff --git a/sync/RWMutex_test.go b/sync/RWMutex_test.go index fb56fbd..fb437d9 100644 --- a/sync/RWMutex_test.go +++ b/sync/RWMutex_test.go @@ -42,9 +42,10 @@ func Test1(t *testing.T) { func Test4(t *testing.T) { var l RWMutex ul := l.RLock() - ul(func() { + ul(func(ulocked bool) (doUlock bool) { ul1 := l.RLock() ul1() + return true }) } @@ -55,8 +56,9 @@ func Test5(t *testing.T) { } }} ul := l.RLock(time.Second, time.Second) - ul(func() { + ul(func(ulocked bool) (doUlock bool) { time.Sleep(time.Second * 2) + return true }) } @@ -67,7 +69,7 @@ func Test8(t *testing.T) { } }} ul := l.Lock() - go ul(func() { time.Sleep(time.Second) }) + go ul(func(ulocked bool) (doUlock bool) { time.Sleep(time.Second); return true }) ul1 := l.RLock(time.Millisecond*500, time.Second) ul1() } @@ -120,8 +122,9 @@ func Test6(t *testing.T) { ul1() c <- 2 }) - ul(func() { + ul(func(ulocked bool) (doUlock bool) { time.Sleep(time.Second) + return true }) c <- 0 if <-c != 1 { @@ -140,11 +143,13 @@ func Test7(t *testing.T) { var l RWMutex ul := l.RLock() ul1 := l.RLock() - ul(func() { + ul(func(ulocked bool) (doUlock bool) { c <- 0 + return true }) - ul1(func() { + ul1(func(ulocked bool) (doUlock bool) { c <- 1 + return true }) if <-c != 0 { t.Fatal() @@ -176,8 +181,9 @@ func Test10(t *testing.T) { func Panic_Test8(t *testing.T) { var l RWMutex ul := l.Lock(time.Second, time.Second) - ul(func() { + ul(func(ulocked bool) (doUlock bool) { time.Sleep(time.Second * 10) + return true }) } @@ -226,6 +232,17 @@ BenchmarkRlock-4 1000000 1069 ns/op 24 B/op 1 allocs/op +# PASS + +goos: linux +goarch: amd64 +pkg: github.com/qydysky/part/sync +cpu: Intel(R) N100 +BenchmarkRlock +BenchmarkRlock-4 + + 4493745 268.9 ns/op 48 B/op 1 allocs/op + PASS */ func BenchmarkRlock(b *testing.B) { @@ -234,3 +251,23 @@ func BenchmarkRlock(b *testing.B) { lock1.RLock()() } } + +/* +goos: linux +goarch: amd64 +pkg: github.com/qydysky/part/sync +cpu: Intel(R) N100 +BenchmarkRlock1 +BenchmarkRlock1-4 + + 7057746 158.2 ns/op 0 B/op 0 allocs/op + +PASS +*/ +func BenchmarkRlock1(b *testing.B) { + var lock1 sync.RWMutex + for i := 0; i < b.N; i++ { + lock1.RLock() + lock1.RUnlock() + } +}