52 lines
1.4 KiB
Go
52 lines
1.4 KiB
Go
|
package quic
|
||
|
|
||
|
import (
|
||
|
"time"
|
||
|
|
||
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
||
|
)
|
||
|
|
||
|
var deadlineSendImmediately = time.Time{}.Add(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine
|
||
|
|
||
|
type connectionTimer struct {
|
||
|
timer *utils.Timer
|
||
|
last time.Time
|
||
|
}
|
||
|
|
||
|
func newTimer() *connectionTimer {
|
||
|
return &connectionTimer{timer: utils.NewTimer()}
|
||
|
}
|
||
|
|
||
|
func (t *connectionTimer) SetRead() {
|
||
|
if deadline := t.timer.Deadline(); deadline != deadlineSendImmediately {
|
||
|
t.last = deadline
|
||
|
}
|
||
|
t.timer.SetRead()
|
||
|
}
|
||
|
|
||
|
func (t *connectionTimer) Chan() <-chan time.Time {
|
||
|
return t.timer.Chan()
|
||
|
}
|
||
|
|
||
|
// SetTimer resets the timer.
|
||
|
// It makes sure that the deadline is strictly increasing.
|
||
|
// This prevents busy-looping in cases where the timer fires, but we can't actually send out a packet.
|
||
|
// This doesn't apply to the pacing deadline, which can be set multiple times to deadlineSendImmediately.
|
||
|
func (t *connectionTimer) SetTimer(idleTimeoutOrKeepAlive, ackAlarm, lossTime, pacing time.Time) {
|
||
|
deadline := idleTimeoutOrKeepAlive
|
||
|
if !ackAlarm.IsZero() && ackAlarm.Before(deadline) && ackAlarm.After(t.last) {
|
||
|
deadline = ackAlarm
|
||
|
}
|
||
|
if !lossTime.IsZero() && lossTime.Before(deadline) && lossTime.After(t.last) {
|
||
|
deadline = lossTime
|
||
|
}
|
||
|
if !pacing.IsZero() && pacing.Before(deadline) {
|
||
|
deadline = pacing
|
||
|
}
|
||
|
t.timer.Reset(deadline)
|
||
|
}
|
||
|
|
||
|
func (t *connectionTimer) Stop() {
|
||
|
t.timer.Stop()
|
||
|
}
|