summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-05-15 18:38:18 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-05-15 18:44:00 +0200
commit207fd644e8a96b5e6d14fa9527901277d34cdd7e (patch)
treec854d228b83d4ebb62c1b547a8ab70dcf2c3e721
parentab02aacdd6536ea1483b939f764c85cbe3f579e6 (diff)
Lock timers on modification
-rw-r--r--timers.go39
1 files changed, 32 insertions, 7 deletions
diff --git a/timers.go b/timers.go
index e132376..b9f6b5a 100644
--- a/timers.go
+++ b/timers.go
@@ -9,6 +9,7 @@ package main
import (
"math/rand"
+ "sync"
"sync/atomic"
"time"
)
@@ -18,28 +19,52 @@ import (
*/
type Timer struct {
- timer *time.Timer
- isPending bool
+ timer *time.Timer
+ modifyingLock sync.Mutex
+ runningLock sync.Mutex
+ isPending bool
}
func (peer *Peer) NewTimer(expirationFunction func(*Peer)) *Timer {
timer := &Timer{}
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.modifyingLock.Unlock()
+
expirationFunction(peer)
+ timer.runningLock.Unlock()
})
timer.timer.Stop()
return timer
}
func (timer *Timer) Mod(d time.Duration) {
+ timer.modifyingLock.Lock()
timer.isPending = true
timer.timer.Reset(d)
+ timer.modifyingLock.Unlock()
}
func (timer *Timer) Del() {
+ timer.modifyingLock.Lock()
timer.isPending = false
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 {
@@ -189,9 +214,9 @@ func (peer *Peer) timersInit() {
}
func (peer *Peer) timersStop() {
- peer.timers.retransmitHandshake.Del()
- peer.timers.sendKeepalive.Del()
- peer.timers.newHandshake.Del()
- peer.timers.zeroKeyMaterial.Del()
- peer.timers.persistentKeepalive.Del()
+ peer.timers.retransmitHandshake.DelSync()
+ peer.timers.sendKeepalive.DelSync()
+ peer.timers.newHandshake.DelSync()
+ peer.timers.zeroKeyMaterial.DelSync()
+ peer.timers.persistentKeepalive.DelSync()
}