github.com/gogf/gf/v2@v2.7.4/os/gmutex/gmutex_z_unit_rwmutex_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gmutex_test 8 9 import ( 10 "context" 11 "testing" 12 "time" 13 14 "github.com/gogf/gf/v2/container/garray" 15 "github.com/gogf/gf/v2/os/glog" 16 "github.com/gogf/gf/v2/os/gmutex" 17 "github.com/gogf/gf/v2/test/gtest" 18 ) 19 20 func Test_RWMutex_RUnlock(t *testing.T) { 21 gtest.C(t, func(t *gtest.T) { 22 mu := gmutex.RWMutex{} 23 mu.RLockFunc(func() { 24 time.Sleep(200 * time.Millisecond) 25 }) 26 }) 27 28 // RLock before Lock 29 gtest.C(t, func(t *gtest.T) { 30 mu := gmutex.RWMutex{} 31 mu.RLock() 32 go func() { 33 mu.Lock() 34 time.Sleep(300 * time.Millisecond) 35 mu.Unlock() 36 }() 37 time.Sleep(100 * time.Millisecond) 38 mu.RUnlock() 39 }) 40 } 41 42 func Test_RWMutex_IsLocked(t *testing.T) { 43 gtest.C(t, func(t *gtest.T) { 44 mu := gmutex.RWMutex{} 45 go func() { 46 mu.LockFunc(func() { 47 time.Sleep(200 * time.Millisecond) 48 }) 49 }() 50 time.Sleep(100 * time.Millisecond) 51 52 go func() { 53 mu.RLockFunc(func() { 54 time.Sleep(200 * time.Millisecond) 55 }) 56 }() 57 }) 58 } 59 60 func Test_RWMutex_Unlock(t *testing.T) { 61 gtest.C(t, func(t *gtest.T) { 62 mu := gmutex.RWMutex{} 63 array := garray.New(true) 64 go func() { 65 mu.LockFunc(func() { 66 array.Append(1) 67 time.Sleep(300 * time.Millisecond) 68 }) 69 }() 70 go func() { 71 time.Sleep(100 * time.Millisecond) 72 mu.LockFunc(func() { 73 array.Append(1) 74 }) 75 }() 76 go func() { 77 time.Sleep(100 * time.Millisecond) 78 mu.LockFunc(func() { 79 array.Append(1) 80 }) 81 }() 82 83 time.Sleep(100 * time.Millisecond) 84 t.Assert(array.Len(), 1) 85 time.Sleep(400 * time.Millisecond) 86 t.Assert(array.Len(), 3) 87 }) 88 } 89 90 func Test_RWMutex_LockFunc(t *testing.T) { 91 gtest.C(t, func(t *gtest.T) { 92 mu := gmutex.RWMutex{} 93 array := garray.New(true) 94 go func() { 95 mu.LockFunc(func() { 96 array.Append(1) 97 time.Sleep(300 * time.Millisecond) 98 }) 99 }() 100 go func() { 101 time.Sleep(100 * time.Millisecond) 102 mu.LockFunc(func() { 103 array.Append(1) 104 }) 105 }() 106 time.Sleep(100 * time.Millisecond) 107 t.Assert(array.Len(), 1) 108 time.Sleep(100 * time.Millisecond) 109 t.Assert(array.Len(), 1) 110 time.Sleep(200 * time.Millisecond) 111 t.Assert(array.Len(), 2) 112 }) 113 } 114 115 func Test_RWMutex_TryLockFunc(t *testing.T) { 116 gtest.C(t, func(t *gtest.T) { 117 mu := gmutex.RWMutex{} 118 array := garray.New(true) 119 go func() { 120 mu.LockFunc(func() { 121 array.Append(1) 122 time.Sleep(300 * time.Millisecond) 123 }) 124 }() 125 go func() { 126 time.Sleep(100 * time.Millisecond) 127 mu.TryLockFunc(func() { 128 array.Append(1) 129 }) 130 }() 131 go func() { 132 time.Sleep(400 * time.Millisecond) 133 mu.TryLockFunc(func() { 134 array.Append(1) 135 }) 136 }() 137 time.Sleep(100 * time.Millisecond) 138 t.Assert(array.Len(), 1) 139 time.Sleep(100 * time.Millisecond) 140 t.Assert(array.Len(), 1) 141 time.Sleep(300 * time.Millisecond) 142 t.Assert(array.Len(), 2) 143 }) 144 } 145 146 func Test_RWMutex_RLockFunc(t *testing.T) { 147 gtest.C(t, func(t *gtest.T) { 148 mu := gmutex.RWMutex{} 149 array := garray.New(true) 150 go func() { 151 mu.LockFunc(func() { 152 array.Append(1) 153 time.Sleep(300 * time.Millisecond) 154 }) 155 }() 156 go func() { 157 time.Sleep(100 * time.Millisecond) 158 mu.RLockFunc(func() { 159 array.Append(1) 160 time.Sleep(100 * time.Millisecond) 161 }) 162 }() 163 time.Sleep(100 * time.Millisecond) 164 t.Assert(array.Len(), 1) 165 time.Sleep(100 * time.Millisecond) 166 t.Assert(array.Len(), 1) 167 time.Sleep(300 * time.Millisecond) 168 t.Assert(array.Len(), 2) 169 }) 170 171 gtest.C(t, func(t *gtest.T) { 172 mu := gmutex.RWMutex{} 173 array := garray.New(true) 174 go func() { 175 time.Sleep(100 * time.Millisecond) 176 mu.RLockFunc(func() { 177 array.Append(1) 178 time.Sleep(100 * time.Millisecond) 179 }) 180 }() 181 go func() { 182 time.Sleep(100 * time.Millisecond) 183 mu.RLockFunc(func() { 184 array.Append(1) 185 time.Sleep(100 * time.Millisecond) 186 }) 187 }() 188 go func() { 189 time.Sleep(100 * time.Millisecond) 190 mu.RLockFunc(func() { 191 array.Append(1) 192 time.Sleep(100 * time.Millisecond) 193 }) 194 }() 195 t.Assert(array.Len(), 0) 196 time.Sleep(200 * time.Millisecond) 197 t.Assert(array.Len(), 3) 198 }) 199 } 200 201 func Test_RWMutex_TryRLockFunc(t *testing.T) { 202 gtest.C(t, func(t *gtest.T) { 203 var ( 204 mu = gmutex.RWMutex{} 205 array = garray.New(true) 206 ) 207 // First writing lock 208 go func() { 209 mu.LockFunc(func() { 210 array.Append(1) 211 glog.Print(context.TODO(), "lock1 done") 212 time.Sleep(2000 * time.Millisecond) 213 }) 214 }() 215 // This goroutine never gets the lock. 216 go func() { 217 time.Sleep(1000 * time.Millisecond) 218 mu.TryRLockFunc(func() { 219 array.Append(1) 220 }) 221 }() 222 for index := 0; index < 1000; index++ { 223 go func() { 224 time.Sleep(4000 * time.Millisecond) 225 mu.TryRLockFunc(func() { 226 array.Append(1) 227 }) 228 }() 229 } 230 time.Sleep(1000 * time.Millisecond) 231 t.Assert(array.Len(), 1) 232 time.Sleep(1000 * time.Millisecond) 233 t.Assert(array.Len(), 1) 234 time.Sleep(1000 * time.Millisecond) 235 t.Assert(array.Len(), 1) 236 time.Sleep(2000 * time.Millisecond) 237 t.Assert(array.Len(), 1001) 238 }) 239 }