gmlock_locker.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. package gmlock
  7. import (
  8. "github.com/gogf/gf/container/gmap"
  9. "github.com/gogf/gf/os/gmutex"
  10. )
  11. // Locker is a memory based locker.
  12. // Note that there's no cache expire mechanism for mutex in locker.
  13. // You need remove certain mutex manually when you do not want use it anymore.
  14. type Locker struct {
  15. m *gmap.StrAnyMap
  16. }
  17. // New creates and returns a new memory locker.
  18. // A memory locker can lock/unlock with dynamic string key.
  19. func New() *Locker {
  20. return &Locker{
  21. m: gmap.NewStrAnyMap(true),
  22. }
  23. }
  24. // Lock locks the <key> with writing lock.
  25. // If there's a write/reading lock the <key>,
  26. // it will block until the lock is released.
  27. func (l *Locker) Lock(key string) {
  28. l.getOrNewMutex(key).Lock()
  29. }
  30. // TryLock tries locking the <key> with writing lock,
  31. // it returns true if success, or it returns false if there's a writing/reading lock the <key>.
  32. func (l *Locker) TryLock(key string) bool {
  33. return l.getOrNewMutex(key).TryLock()
  34. }
  35. // Unlock unlocks the writing lock of the <key>.
  36. func (l *Locker) Unlock(key string) {
  37. if v := l.m.Get(key); v != nil {
  38. v.(*gmutex.Mutex).Unlock()
  39. }
  40. }
  41. // RLock locks the <key> with reading lock.
  42. // If there's a writing lock on <key>,
  43. // it will blocks until the writing lock is released.
  44. func (l *Locker) RLock(key string) {
  45. l.getOrNewMutex(key).RLock()
  46. }
  47. // TryRLock tries locking the <key> with reading lock.
  48. // It returns true if success, or if there's a writing lock on <key>, it returns false.
  49. func (l *Locker) TryRLock(key string) bool {
  50. return l.getOrNewMutex(key).TryRLock()
  51. }
  52. // RUnlock unlocks the reading lock of the <key>.
  53. func (l *Locker) RUnlock(key string) {
  54. if v := l.m.Get(key); v != nil {
  55. v.(*gmutex.Mutex).RUnlock()
  56. }
  57. }
  58. // LockFunc locks the <key> with writing lock and callback function <f>.
  59. // If there's a write/reading lock the <key>,
  60. // it will block until the lock is released.
  61. //
  62. // It releases the lock after <f> is executed.
  63. func (l *Locker) LockFunc(key string, f func()) {
  64. l.Lock(key)
  65. defer l.Unlock(key)
  66. f()
  67. }
  68. // RLockFunc locks the <key> with reading lock and callback function <f>.
  69. // If there's a writing lock the <key>,
  70. // it will block until the lock is released.
  71. //
  72. // It releases the lock after <f> is executed.
  73. func (l *Locker) RLockFunc(key string, f func()) {
  74. l.RLock(key)
  75. defer l.RUnlock(key)
  76. f()
  77. }
  78. // TryLockFunc locks the <key> with writing lock and callback function <f>.
  79. // It returns true if success, or else if there's a write/reading lock the <key>, it return false.
  80. //
  81. // It releases the lock after <f> is executed.
  82. func (l *Locker) TryLockFunc(key string, f func()) bool {
  83. if l.TryLock(key) {
  84. defer l.Unlock(key)
  85. f()
  86. return true
  87. }
  88. return false
  89. }
  90. // TryRLockFunc locks the <key> with reading lock and callback function <f>.
  91. // It returns true if success, or else if there's a writing lock the <key>, it returns false.
  92. //
  93. // It releases the lock after <f> is executed.
  94. func (l *Locker) TryRLockFunc(key string, f func()) bool {
  95. if l.TryRLock(key) {
  96. defer l.RUnlock(key)
  97. f()
  98. return true
  99. }
  100. return false
  101. }
  102. // Remove removes mutex with given <key> from locker.
  103. func (l *Locker) Remove(key string) {
  104. l.m.Remove(key)
  105. }
  106. // Clear removes all mutexes from locker.
  107. func (l *Locker) Clear() {
  108. l.m.Clear()
  109. }
  110. // getOrNewMutex returns the mutex of given <key> if it exists,
  111. // or else creates and returns a new one.
  112. func (l *Locker) getOrNewMutex(key string) *gmutex.Mutex {
  113. return l.m.GetOrSetFuncLock(key, func() interface{} {
  114. return gmutex.New()
  115. }).(*gmutex.Mutex)
  116. }