github.com/sagernet/quic-go@v0.43.1-beta.1/ech/connection_timer.go (about) 1 package quic 2 3 import ( 4 "time" 5 6 "github.com/sagernet/quic-go/internal/utils" 7 ) 8 9 var deadlineSendImmediately = time.Time{}.Add(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine 10 11 type connectionTimer struct { 12 timer *utils.Timer 13 last time.Time 14 } 15 16 func newTimer() *connectionTimer { 17 return &connectionTimer{timer: utils.NewTimer()} 18 } 19 20 func (t *connectionTimer) SetRead() { 21 if deadline := t.timer.Deadline(); deadline != deadlineSendImmediately { 22 t.last = deadline 23 } 24 t.timer.SetRead() 25 } 26 27 func (t *connectionTimer) Chan() <-chan time.Time { 28 return t.timer.Chan() 29 } 30 31 // SetTimer resets the timer. 32 // It makes sure that the deadline is strictly increasing. 33 // This prevents busy-looping in cases where the timer fires, but we can't actually send out a packet. 34 // This doesn't apply to the pacing deadline, which can be set multiple times to deadlineSendImmediately. 35 func (t *connectionTimer) SetTimer(idleTimeoutOrKeepAlive, ackAlarm, lossTime, pacing time.Time) { 36 deadline := idleTimeoutOrKeepAlive 37 if !ackAlarm.IsZero() && ackAlarm.Before(deadline) && ackAlarm.After(t.last) { 38 deadline = ackAlarm 39 } 40 if !lossTime.IsZero() && lossTime.Before(deadline) && lossTime.After(t.last) { 41 deadline = lossTime 42 } 43 if !pacing.IsZero() && pacing.Before(deadline) { 44 deadline = pacing 45 } 46 t.timer.Reset(deadline) 47 } 48 49 func (t *connectionTimer) Stop() { 50 t.timer.Stop() 51 }