| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package mint
- import (
- "time"
- )
- // This is a simple timer implementation. Timers are stored in a sorted
- // list.
- // TODO(ekr@rtfm.com): Add a way to uncouple these from the system
- // clock.
- type timerCb func() error
- type timer struct {
- label string
- cb timerCb
- deadline time.Time
- duration uint32
- }
- type timerSet struct {
- ts []*timer
- }
- func newTimerSet() *timerSet {
- return &timerSet{}
- }
- func (ts *timerSet) start(label string, cb timerCb, delayMs uint32) *timer {
- now := time.Now()
- t := timer{
- label,
- cb,
- now.Add(time.Millisecond * time.Duration(delayMs)),
- delayMs,
- }
- logf(logTypeHandshake, "Timer %s set [%v -> %v]", t.label, now, t.deadline)
- var i int
- ntimers := len(ts.ts)
- for i = 0; i < ntimers; i++ {
- if t.deadline.Before(ts.ts[i].deadline) {
- break
- }
- }
- tmp := make([]*timer, 0, ntimers+1)
- tmp = append(tmp, ts.ts[:i]...)
- tmp = append(tmp, &t)
- tmp = append(tmp, ts.ts[i:]...)
- ts.ts = tmp
- return &t
- }
- // TODO(ekr@rtfm.com): optimize this now that the list is sorted.
- // We should be able to do just one list manipulation, as long
- // as we're careful about how we handle inserts during callbacks.
- func (ts *timerSet) check(now time.Time) error {
- for i, t := range ts.ts {
- if now.After(t.deadline) {
- ts.ts = append(ts.ts[:i], ts.ts[:i+1]...)
- if t.cb != nil {
- logf(logTypeHandshake, "Timer %s expired [%v > %v]", t.label, now, t.deadline)
- cb := t.cb
- t.cb = nil
- err := cb()
- if err != nil {
- return err
- }
- }
- } else {
- break
- }
- }
- return nil
- }
- // Returns the next time any of the timers would fire.
- func (ts *timerSet) remaining() (bool, time.Duration) {
- for _, t := range ts.ts {
- if t.cb != nil {
- return true, time.Until(t.deadline)
- }
- }
- return false, time.Duration(0)
- }
- func (ts *timerSet) cancel(label string) {
- for _, t := range ts.ts {
- if t.label == label {
- t.cancel()
- }
- }
- }
- func (ts *timerSet) getTimer(label string) *timer {
- for _, t := range ts.ts {
- if t.label == label && t.cb != nil {
- return t
- }
- }
- return nil
- }
- func (ts *timerSet) getAllTimers() []string {
- var ret []string
- for _, t := range ts.ts {
- if t.cb != nil {
- ret = append(ret, t.label)
- }
- }
- return ret
- }
- func (t *timer) cancel() {
- logf(logTypeHandshake, "Timer %s cancelled", t.label)
- t.cb = nil
- t.label = ""
- }
|