throttle_timer: fix race, use mtx instead of atomic
This commit is contained in:
parent
9dc4dc1960
commit
930880f574
|
@ -1,7 +1,7 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,12 +12,14 @@ If a long continuous burst of .Set() calls happens, ThrottleTimer fires
|
||||||
at most once every "dur".
|
at most once every "dur".
|
||||||
*/
|
*/
|
||||||
type ThrottleTimer struct {
|
type ThrottleTimer struct {
|
||||||
Name string
|
Name string
|
||||||
Ch chan struct{}
|
Ch chan struct{}
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
dur time.Duration
|
dur time.Duration
|
||||||
|
|
||||||
|
mtx sync.Mutex
|
||||||
timer *time.Timer
|
timer *time.Timer
|
||||||
isSet uint32
|
isSet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
|
func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
|
||||||
|
@ -30,9 +32,11 @@ func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ThrottleTimer) fireRoutine() {
|
func (t *ThrottleTimer) fireRoutine() {
|
||||||
|
t.mtx.Lock()
|
||||||
|
defer t.mtx.Unlock()
|
||||||
select {
|
select {
|
||||||
case t.Ch <- struct{}{}:
|
case t.Ch <- struct{}{}:
|
||||||
atomic.StoreUint32(&t.isSet, 0)
|
t.isSet = false
|
||||||
case <-t.quit:
|
case <-t.quit:
|
||||||
// do nothing
|
// do nothing
|
||||||
default:
|
default:
|
||||||
|
@ -41,13 +45,18 @@ func (t *ThrottleTimer) fireRoutine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ThrottleTimer) Set() {
|
func (t *ThrottleTimer) Set() {
|
||||||
if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
|
t.mtx.Lock()
|
||||||
|
defer t.mtx.Unlock()
|
||||||
|
if !t.isSet {
|
||||||
|
t.isSet = true
|
||||||
t.timer.Reset(t.dur)
|
t.timer.Reset(t.dur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ThrottleTimer) Unset() {
|
func (t *ThrottleTimer) Unset() {
|
||||||
atomic.StoreUint32(&t.isSet, 0)
|
t.mtx.Lock()
|
||||||
|
defer t.mtx.Unlock()
|
||||||
|
t.isSet = false
|
||||||
t.timer.Stop()
|
t.timer.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,5 +67,7 @@ func (t *ThrottleTimer) Stop() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
close(t.quit)
|
close(t.quit)
|
||||||
|
t.mtx.Lock()
|
||||||
|
defer t.mtx.Unlock()
|
||||||
return t.timer.Stop()
|
return t.timer.Stop()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue