40 lines
585 B
Go
40 lines
585 B
Go
package telegram
|
|
|
|
import "sync"
|
|
|
|
type keyedLocker struct {
|
|
mu sync.Mutex
|
|
locks map[int64]*keyedLock
|
|
}
|
|
|
|
type keyedLock struct {
|
|
mu sync.Mutex
|
|
refs int
|
|
}
|
|
|
|
func newKeyedLocker() *keyedLocker {
|
|
return &keyedLocker{locks: make(map[int64]*keyedLock)}
|
|
}
|
|
|
|
func (l *keyedLocker) Lock(key int64) func() {
|
|
l.mu.Lock()
|
|
lock := l.locks[key]
|
|
if lock == nil {
|
|
lock = &keyedLock{}
|
|
l.locks[key] = lock
|
|
}
|
|
lock.refs++
|
|
l.mu.Unlock()
|
|
|
|
lock.mu.Lock()
|
|
return func() {
|
|
lock.mu.Unlock()
|
|
l.mu.Lock()
|
|
lock.refs--
|
|
if lock.refs == 0 {
|
|
delete(l.locks, key)
|
|
}
|
|
l.mu.Unlock()
|
|
}
|
|
}
|