mirror of
https://github.com/PeernetOfficial/Abstraction.git
synced 2026-07-22 05:07:50 +01:00
56 lines
1.1 KiB
Go
56 lines
1.1 KiB
Go
package locker
|
|
|
|
import "sync"
|
|
|
|
// Locker type for map of mutexes and self lock to add new mutex to map
|
|
type Locker struct {
|
|
pool sync.Pool
|
|
locks sync.Map
|
|
}
|
|
|
|
// Initialize - return initialized locker struct
|
|
func Initialize() *Locker {
|
|
return &Locker{
|
|
pool: sync.Pool{
|
|
New: func() interface{} {
|
|
return new(sync.RWMutex)
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// Lock - locks mutex
|
|
func (lkr *Locker) Lock(key interface{}) func() {
|
|
lkr.getLock(key).Lock()
|
|
return func() {
|
|
lkr.getLock(key).Unlock()
|
|
}
|
|
}
|
|
|
|
// Unlock - unlocks mutex
|
|
func (lkr *Locker) Unlock(key interface{}) {
|
|
lkr.getLock(key).Unlock()
|
|
}
|
|
|
|
// RLock - locks rw for reading
|
|
func (lkr *Locker) RLock(key interface{}) func() {
|
|
lkr.getLock(key).RLock()
|
|
return func() {
|
|
lkr.getLock(key).RUnlock()
|
|
}
|
|
}
|
|
|
|
// RUnlock - unlocks a single RLock call
|
|
func (lkr *Locker) RUnlock(key interface{}) {
|
|
lkr.getLock(key).RUnlock()
|
|
}
|
|
|
|
func (lkr *Locker) getLock(key interface{}) *sync.RWMutex {
|
|
newLock := lkr.pool.Get()
|
|
lock, stored := lkr.locks.LoadOrStore(key, newLock)
|
|
if stored {
|
|
lkr.pool.Put(newLock)
|
|
}
|
|
return lock.(*sync.RWMutex)
|
|
}
|