LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package time | 5 package time |
6 | 6 |
7 // Sleep pauses the current goroutine for the duration d. | 7 // Sleep pauses the current goroutine for the duration d. |
8 func Sleep(d Duration) | 8 func Sleep(d Duration) |
9 | 9 |
10 func nano() int64 { | 10 func nano() int64 { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 }, | 115 }, |
116 } | 116 } |
117 startTimer(&t.r) | 117 startTimer(&t.r) |
118 return t | 118 return t |
119 } | 119 } |
120 | 120 |
121 func goFunc(now int64, arg interface{}) { | 121 func goFunc(now int64, arg interface{}) { |
122 go arg.(func())() | 122 go arg.(func())() |
123 } | 123 } |
124 | 124 |
125 // Expirator - interface for passing into SetupExpire | 125 // Expirator - callback interface for passing into EmbedTimer.SetupExpire |
126 type Expirator interface { | 126 type Expirator interface { |
127 » // Expire will be runned by timer in a priviledged goroutine | 127 » // Expire will be called in separate goroutine when duration elapsed. |
128 » // so that, you should run only fast non-blocking operation inside: | |
129 » // - check/set variables (perhaps, using sync.atomic) | |
130 » // - nonblocking send to a channel (ensure channel have enough buffer or
use select with default) | |
131 » // - Mutex.Unlock() | |
132 » // - Cond.Signal() or Cond.Broadcast() | |
133 » // For anything more time consuming, you should run gorouting, or use Af
terFunc | |
134 Expire() | 128 Expire() |
135 } | 129 } |
136 | 130 |
137 // SetupExpire initialize already allocated timer to call e.Expire() after elaps
ed duration. | 131 // InplaceTimer - timer suitable for embeding into user structs. |
138 // It panics, if timer were already initialized or get from NewTimer or AfterFun
c. | 132 // It needs no separate allocation, but it is your responsibility to not |
139 // This is dangerous feature for those, who uses very large amount of timers, an
d do not | 133 // copy it or overwrite. |
140 // want to pay for separate memory allocation for Timer and func() when you want
to call method | 134 // Consider use it only if you ought to create more than hundred of thousands |
141 // on a same object, which holds the timer. | 135 // of timers per second, which are likely to be stopped (ie unused). |
142 // You should consider using it only if you ought to create more than hundred of
thousands | 136 // For most other cases AfterFunc and NewTimer should be enough. |
143 // of timers per second, which are likely to be stopped, and which callback have
a fast path, | 137 type EmbedTimer struct { |
144 // which do not block or panic (for slow or blocking path you should run gorouti
ne by yourself). | 138 » Timer |
145 // If you allocate timer by yourself, you should be careful to not accidentially | 139 } |
146 // overwrite it or copy it to other place. | 140 |
147 func (t *Timer) SetupExpire(d Duration, e Expirator) { | 141 // SetupExpire initialize timer to call e.Expire() after elapsed duration. |
| 142 // It panics, if timer were already initialized. |
| 143 func (t *EmbedTimer) SetupExpire(d Duration, e Expirator) { |
148 if t.r.f != nil { | 144 if t.r.f != nil { |
149 » » panic("Timer.SetupExpire should be called on uninitialized timer
only") | 145 » » panic("EmbedTimer.SetupExpire should be called on uninitialized
timer only") |
150 } | 146 } |
151 t.r = runtimeTimer{ | 147 t.r = runtimeTimer{ |
152 when: when(d), | 148 when: when(d), |
153 f: goExpire, | 149 f: goExpire, |
154 arg: e, | 150 arg: e, |
155 } | 151 } |
156 startTimer(&t.r) | 152 startTimer(&t.r) |
157 } | 153 } |
158 | 154 |
159 func goExpire(now int64, arg interface{}) { | 155 func goExpire(now int64, arg interface{}) { |
160 » arg.(Expirator).Expire() | 156 » go arg.(Expirator).Expire() |
161 } | 157 } |
162 | 158 |
163 // Initialized returns, were timer setted up or not. | 159 // Initialized returns, were timer setted up or not. |
164 // Use it with custom allocated timers only. | 160 func (t *EmbedTimer) Initialized() bool { |
165 func (t *Timer) Initialized() bool { | |
166 return t.r.f != nil | 161 return t.r.f != nil |
167 } | 162 } |
168 | 163 |
169 // Deinitialize clears up timer, so that it could be used again. | 164 // Deinitialize clears up timer, so that SetupExpire could be called again. |
170 // Use it with custom allocated timers only. | 165 func (t *EmbedTimer) Deinitialize() { |
171 func (t *Timer) Deinitialize() { | |
172 if t.r.f != nil { | 166 if t.r.f != nil { |
173 if t.r.i != -1 { | 167 if t.r.i != -1 { |
174 stopTimer(&t.r) | 168 stopTimer(&t.r) |
175 } | 169 } |
176 » » *t = Timer{} | 170 » » *t = EmbedTimer{} |
177 } | 171 } |
178 } | 172 } |
LEFT | RIGHT |