package v2raykcp import ( "sync/atomic" "time" ) type Updater struct { interval int64 shouldContinue func() bool shouldTerminate func() bool updateFunc func() notifier chan struct{} } func NewUpdater(interval uint32, shouldContinue func() bool, shouldTerminate func() bool, updateFunc func()) *Updater { u := &Updater{ interval: int64(time.Duration(interval) * time.Millisecond), shouldContinue: shouldContinue, shouldTerminate: shouldTerminate, updateFunc: updateFunc, notifier: make(chan struct{}, 1), } return u } func (u *Updater) WakeUp() { select { case u.notifier <- struct{}{}: go u.run() default: } } func (u *Updater) run() { defer func() { <-u.notifier }() if u.shouldTerminate() { return } ticker := time.NewTicker(u.Interval()) defer ticker.Stop() for u.shouldContinue() { u.updateFunc() <-ticker.C } } func (u *Updater) Interval() time.Duration { return time.Duration(atomic.LoadInt64(&u.interval)) } func (u *Updater) SetInterval(d time.Duration) { atomic.StoreInt64(&u.interval, int64(d)) }