gmlock_locker.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. "sync"
  9. "github.com/gogf/gf/v2/container/gmap"
  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.(*sync.RWMutex).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.(*sync.RWMutex).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) *sync.RWMutex {
  113. return l.m.GetOrSetFuncLock(key, func() interface{} {
  114. return &sync.RWMutex{}
  115. }).(*sync.RWMutex)
  116. }