-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimer.go
More file actions
128 lines (107 loc) · 2.06 KB
/
timer.go
File metadata and controls
128 lines (107 loc) · 2.06 KB
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package clock
import (
"sync"
"time"
)
type Timer struct {
C <-chan time.Time
// real
timer *time.Timer
// mock
f func() // AfterFunc function
now func() time.Time // fuction to get the current time
c chan<- time.Time // send-only channel to access the receive-only channel C
add func() // callback when timer becomes active
remove func() // callback when timer becomes inactive
mu sync.Mutex
target_ time.Time // target time for firing
stopped bool // true if the timer has fired or has been stopped
}
func newMockTimer(target time.Time, f func(), now func() time.Time, add func(), remove func()) *Timer {
if now == nil {
panic("nil now")
}
timer := &Timer{
target_: target,
f: f,
now: now,
add: add,
remove: remove,
}
if f == nil {
c := make(chan time.Time, 1)
timer.C = c
timer.c = c
}
return timer
}
func newRealTimer(d time.Duration, f func()) *Timer {
var realTimer *time.Timer
if f != nil {
realTimer = time.AfterFunc(d, f)
} else {
realTimer = time.NewTimer(d)
}
return &Timer{
C: realTimer.C,
timer: realTimer,
}
}
func (self *Timer) target() time.Time {
self.mu.Lock()
defer self.mu.Unlock()
return self.target_
}
func (self *Timer) stop() bool {
self.mu.Lock()
if self.stopped {
self.mu.Unlock()
return false
}
self.stopped = true
self.mu.Unlock()
if self.remove != nil {
self.remove()
}
return true
}
func (self *Timer) fire(t time.Time) bool {
if !self.stop() {
return false
}
if self.f != nil {
self.f()
} else {
select {
case self.c <- t:
default:
}
}
return true
}
func (self *Timer) Stop() bool {
if self.timer != nil {
return self.timer.Stop()
}
if !self.stop() {
return false
}
return true
}
func (self *Timer) Reset(d time.Duration) bool {
if self.timer != nil {
return self.timer.Reset(d)
}
var active bool
target := self.now().Add(d)
self.mu.Lock()
if !self.stopped {
active = true
}
self.target_ = target
self.mu.Unlock()
if self.add != nil {
self.add()
}
return active
}