This repository has been archived by the owner on Oct 11, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
/
timer.go
82 lines (67 loc) · 1.43 KB
/
timer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package clock
import (
"time"
)
type mockTimer struct {
c chan time.Time
release chan bool
lock chan struct{}
clock Clock
active bool
trigger <-chan time.Time
}
var _ Timer = new(mockTimer)
func (m *mockTimer) setInactive() {
// If a release was sent in the meantime, that means a new timer
// was started or that we already stopped manually
select {
case m.lock <- struct{}{}:
defer func() { <-m.lock }()
case <-m.release:
return
}
m.active = false
}
func (m *mockTimer) wait() {
select {
case <-m.trigger:
m.setInactive()
m.c <- m.clock.Now()
case <-m.release:
}
}
func (m *mockTimer) Chan() <-chan time.Time {
return m.c
}
func (m *mockTimer) Reset(d time.Duration) bool {
var wasActive bool
m.lock <- struct{}{}
defer func() { <-m.lock }()
wasActive, m.active = m.active, true
m.trigger = m.clock.After(d)
if wasActive {
m.release <- true
}
go m.wait()
return wasActive
}
func (m *mockTimer) Stop() bool {
var wasActive bool
m.lock <- struct{}{}
defer func() { <-m.lock }()
wasActive, m.active = m.active, false
if wasActive {
m.release <- true
}
return wasActive
}
// NewMockTimer creates a new Timer using the provided Clock. You should not use this
// directly outside of unit tests; use Clock.NewTimer().
func NewMockTimer(c Clock) Timer {
return &mockTimer{
c: make(chan time.Time, 1),
release: make(chan bool),
lock: make(chan struct{}, 1),
clock: c,
}
}