better locking for account guard

This commit is contained in:
Radu Ioan Fericean
2014-01-10 11:46:18 +02:00
parent 2cd548b810
commit f393b600d4

View File

@@ -30,7 +30,7 @@ func init() {
type AccountLock struct {
queue map[string]chan bool
sync.Mutex
sync.RWMutex
}
func NewAccountLock() *AccountLock {
@@ -38,13 +38,15 @@ func NewAccountLock() *AccountLock {
}
func (cm *AccountLock) GuardGetCost(name string, handler func() (*CallCost, error)) (reply *CallCost, err error) {
cm.Lock()
cm.RLock()
lock, exists := AccLock.queue[name]
cm.RUnlock()
if !exists {
cm.Lock()
lock = make(chan bool, 1)
AccLock.queue[name] = lock
cm.Unlock()
}
cm.Unlock()
lock <- true
reply, err = handler()
<-lock
@@ -52,13 +54,35 @@ func (cm *AccountLock) GuardGetCost(name string, handler func() (*CallCost, erro
}
func (cm *AccountLock) Guard(name string, handler func() (float64, error)) (reply float64, err error) {
cm.RLock()
lock, exists := AccLock.queue[name]
cm.RUnlock()
if !exists {
cm.Lock()
lock = make(chan bool, 1)
AccLock.queue[name] = lock
cm.Unlock()
}
lock <- true
reply, err = handler()
<-lock
return
}
func (cm *AccountLock) GuardMany(names []string, handler func() (float64, error)) (reply float64, err error) {
for _, name := range names {
cm.RLock()
lock, exists := AccLock.queue[name]
cm.RUnlock()
if !exists {
cm.Lock()
lock = make(chan bool, 1)
AccLock.queue[name] = lock
cm.Unlock()
}
lock <- true
reply, err = handler()
<-lock
}
return
}