]> 127.0.0.1 Git - part/.git/commitdiff
add v0.28.0+202307272ddbeb9
authorqydysky <qydysky@foxmail.com>
Thu, 27 Jul 2023 01:54:08 +0000 (09:54 +0800)
committerqydysky <qydysky@foxmail.com>
Thu, 27 Jul 2023 01:54:08 +0000 (09:54 +0800)
sync/RWMutex.go
sync/RWMutex_test.go

index f3f8b458bb1052cf515ca0fd61033d412af7abea..e2f2a931385920421b677c50953f71e6f97b2646 100644 (file)
@@ -93,11 +93,17 @@ func tof(to time.Duration) (inTimeCall func() (called bool)) {
 //
 // 不要在Rlock内设置变量,有DATA RACE风险
 func (m *RWMutex) RLock(to ...time.Duration) (unlockf func()) {
-       _, rlcLoop := lcas(&m.rlc, ulock, rlock)
-       if e := rlcLoop(to...); e != nil {
-               panic(e)
+       if m.read.Add(1) == 1 {
+               _, rlcLoop := cas(&m.rlc, ulock, rlock)
+               if e := rlcLoop(to...); e != nil {
+                       panic(e)
+               }
+       } else {
+               _, rlcLoop := lcas(&m.rlc, ulock, rlock)
+               if e := rlcLoop(to...); e != nil {
+                       panic(e)
+               }
        }
-       m.read.Add(1)
        var callC atomic.Bool
        var done func() (called bool)
        if len(to) > 1 {
index 7f45ccd5664ab5a8565b53e64807444660d24835..07644f94104a35844fe118d46987a5e0ebe4a86e 100644 (file)
@@ -14,6 +14,18 @@ func check(l *RWMutex, r, read int32) {
        }
 }
 
+func Test0(t *testing.T) {
+       var l RWMutex
+       ul := l.RLock()
+       go func() {
+               l.Lock()()
+       }()
+       go func() {
+               l.RLock()()
+       }()
+       ul()
+}
+
 // ulock rlock rlock
 func Test1(t *testing.T) {
        var l RWMutex
@@ -53,7 +65,7 @@ func Test3(t *testing.T) {
        ul := l.Lock()
        check(&l, lock, 0)
        time.AfterFunc(time.Second, func() {
-               check(&l, lock, 0)
+               check(&l, lock, 1)
                ul()
        })
        c := time.Now()
@@ -101,25 +113,6 @@ func Panic_Test5(t *testing.T) {
        check(&l, ulock, 0)
 }
 
-// ulock lock rlock
-func Test6(t *testing.T) {
-       var l RWMutex
-       ul := l.Lock()
-       check(&l, lock, 0)
-       time.AfterFunc(time.Second, func() {
-               check(&l, lock, 0)
-               ul()
-       })
-       c := time.Now()
-       ul1 := l.RLock()
-       check(&l, rlock, 1)
-       if time.Since(c) < time.Second {
-               t.Fail()
-       }
-       ul1()
-       check(&l, ulock, 0)
-}
-
 func BenchmarkRlock(b *testing.B) {
        var lock1 RWMutex
        var a bool