Lock timers on modification

This commit is contained in:
Jason A. Donenfeld 2018-05-15 18:38:18 +02:00
parent ab02aacdd6
commit 207fd644e8

View file

@ -9,6 +9,7 @@ package main
import ( import (
"math/rand" "math/rand"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
) )
@ -19,27 +20,51 @@ import (
type Timer struct { type Timer struct {
timer *time.Timer timer *time.Timer
modifyingLock sync.Mutex
runningLock sync.Mutex
isPending bool isPending bool
} }
func (peer *Peer) NewTimer(expirationFunction func(*Peer)) *Timer { func (peer *Peer) NewTimer(expirationFunction func(*Peer)) *Timer {
timer := &Timer{} timer := &Timer{}
timer.timer = time.AfterFunc(time.Hour, func() { timer.timer = time.AfterFunc(time.Hour, func() {
timer.runningLock.Lock()
timer.modifyingLock.Lock()
if !timer.isPending {
timer.modifyingLock.Unlock()
timer.runningLock.Unlock()
return
}
timer.isPending = false timer.isPending = false
timer.modifyingLock.Unlock()
expirationFunction(peer) expirationFunction(peer)
timer.runningLock.Unlock()
}) })
timer.timer.Stop() timer.timer.Stop()
return timer return timer
} }
func (timer *Timer) Mod(d time.Duration) { func (timer *Timer) Mod(d time.Duration) {
timer.modifyingLock.Lock()
timer.isPending = true timer.isPending = true
timer.timer.Reset(d) timer.timer.Reset(d)
timer.modifyingLock.Unlock()
} }
func (timer *Timer) Del() { func (timer *Timer) Del() {
timer.modifyingLock.Lock()
timer.isPending = false timer.isPending = false
timer.timer.Stop() timer.timer.Stop()
timer.modifyingLock.Unlock()
}
func (timer *Timer) DelSync() {
timer.Del()
timer.runningLock.Lock()
timer.Del()
timer.runningLock.Unlock()
} }
func (peer *Peer) timersActive() bool { func (peer *Peer) timersActive() bool {
@ -189,9 +214,9 @@ func (peer *Peer) timersInit() {
} }
func (peer *Peer) timersStop() { func (peer *Peer) timersStop() {
peer.timers.retransmitHandshake.Del() peer.timers.retransmitHandshake.DelSync()
peer.timers.sendKeepalive.Del() peer.timers.sendKeepalive.DelSync()
peer.timers.newHandshake.Del() peer.timers.newHandshake.DelSync()
peer.timers.zeroKeyMaterial.Del() peer.timers.zeroKeyMaterial.DelSync()
peer.timers.persistentKeepalive.Del() peer.timers.persistentKeepalive.DelSync()
} }