OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 // Timer heap implemented as a array-based binary heap[0]. | 7 // Timer heap implemented as a array-based binary heap[0]. |
8 // This allows for O(1) `first`, O(log(n)) `remove`/`removeFirst` and O(log(n)) | 8 // This allows for O(1) `first`, O(log(n)) `remove`/`removeFirst` and O(log(n)) |
9 // `add`. | 9 // `add`. |
10 // | 10 // |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 // Disables the timer. | 121 // Disables the timer. |
122 static const int _NO_TIMER = -1; | 122 static const int _NO_TIMER = -1; |
123 | 123 |
124 // Timers are ordered by wakeup time. | 124 // Timers are ordered by wakeup time. |
125 static _TimerHeap _heap = new _TimerHeap(); | 125 static _TimerHeap _heap = new _TimerHeap(); |
126 static _Timer _firstZeroTimer; | 126 static _Timer _firstZeroTimer; |
127 static _Timer _lastZeroTimer; | 127 static _Timer _lastZeroTimer; |
128 static int _idCount = 0; | 128 static int _idCount = 0; |
129 | 129 |
130 static RawReceivePort _receivePort; | 130 static RawReceivePort _receivePort; |
131 static SendPort _sendPort; | |
131 static bool _handlingCallbacks = false; | 132 static bool _handlingCallbacks = false; |
132 | 133 |
133 Function _callback; | 134 Function _callback; |
134 int _milliSeconds; | 135 int _milliSeconds; |
135 int _wakeupTime = 0; | 136 int _wakeupTime = 0; |
136 var _indexOrNext; | 137 var _indexOrNext; |
137 int _id = -1; | 138 int _id = -1; |
138 | 139 |
139 static Timer _createTimer(void callback(Timer timer), | 140 static Timer _createTimer(void callback(Timer timer), |
140 int milliSeconds, | 141 int milliSeconds, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 void _advanceWakeupTime() { | 200 void _advanceWakeupTime() { |
200 assert(_milliSeconds >= 0); | 201 assert(_milliSeconds >= 0); |
201 _wakeupTime += _milliSeconds; | 202 _wakeupTime += _milliSeconds; |
202 } | 203 } |
203 | 204 |
204 // Adds a timer to the timer list. Timers with the same wakeup time are | 205 // Adds a timer to the timer list. Timers with the same wakeup time are |
205 // enqueued in order and notified in FIFO order. | 206 // enqueued in order and notified in FIFO order. |
206 bool _addTimerToHeap() { | 207 bool _addTimerToHeap() { |
207 if (_wakeupTime == 0) { | 208 if (_wakeupTime == 0) { |
208 if (_firstZeroTimer == null) { | 209 if (_firstZeroTimer == null) { |
209 _lastZeroTimer = _firstZeroTimer = this; | 210 _lastZeroTimer = _firstZeroTimer = this; |
Ivan Posva
2014/02/05 16:54:46
_lastZeroTimer = this;
_firstZeroTimer = this;
Th
| |
210 return true; | 211 return true; |
211 } else { | 212 } else { |
212 _lastZeroTimer = _lastZeroTimer._indexOrNext = this; | 213 _lastZeroTimer = _lastZeroTimer._indexOrNext = this; |
213 return false; | 214 return false; |
214 } | 215 } |
215 } else { | 216 } else { |
216 _id = _idCount++; | 217 _id = _idCount++; |
217 _heap.add(this); | 218 _heap.add(this); |
218 return _firstZeroTimer == null && _heap.isFirst(this); | 219 return _firstZeroTimer == null && _heap.isFirst(this); |
219 } | 220 } |
(...skipping 14 matching lines...) Expand all Loading... | |
234 if (_receivePort != null) { | 235 if (_receivePort != null) { |
235 _EventHandler._sendData(null, _receivePort, _NO_TIMER); | 236 _EventHandler._sendData(null, _receivePort, _NO_TIMER); |
236 _shutdownTimerHandler(); | 237 _shutdownTimerHandler(); |
237 } | 238 } |
238 } else { | 239 } else { |
239 if (_receivePort == null) { | 240 if (_receivePort == null) { |
240 // Create a receive port and register a message handler for the timer | 241 // Create a receive port and register a message handler for the timer |
241 // events. | 242 // events. |
242 _createTimerHandler(); | 243 _createTimerHandler(); |
243 } | 244 } |
244 _EventHandler._sendData(null, | 245 if (_firstZeroTimer != null) { |
245 _receivePort, | 246 _sendPort.send(null); |
246 _firstZeroTimer != null ? | 247 } else { |
247 0 : _heap.first._wakeupTime); | 248 _EventHandler._sendData(null, |
249 _receivePort, | |
250 _heap.first._wakeupTime); | |
251 } | |
248 } | 252 } |
249 } | 253 } |
250 | 254 |
251 static void _handleTimeout(_) { | 255 static void _handleTimeout(_) { |
252 int currentTime = new DateTime.now().millisecondsSinceEpoch; | 256 int currentTime = new DateTime.now().millisecondsSinceEpoch; |
253 // Collect all pending timers. | 257 // Collect all pending timers. |
254 var timer = _firstZeroTimer; | 258 var timer = _firstZeroTimer; |
255 var nextTimer = _lastZeroTimer; | 259 var nextTimer = _lastZeroTimer; |
256 _firstZeroTimer = _lastZeroTimer = null; | 260 _firstZeroTimer = _lastZeroTimer = null; |
Ivan Posva
2014/02/05 16:54:46
ditto
| |
257 while (_heap.isNotEmpty && _heap.first._wakeupTime <= currentTime) { | 261 while (_heap.isNotEmpty && _heap.first._wakeupTime <= currentTime) { |
258 var next = _heap.removeFirst(); | 262 var next = _heap.removeFirst(); |
259 if (timer == null) { | 263 if (timer == null) { |
260 nextTimer = timer = next; | 264 nextTimer = timer = next; |
Ivan Posva
2014/02/05 16:54:46
ditto. Here and other places.
| |
261 } else { | 265 } else { |
262 nextTimer = nextTimer._indexOrNext = next; | 266 nextTimer = nextTimer._indexOrNext = next; |
263 } | 267 } |
264 } | 268 } |
265 | 269 |
266 // Trigger all of the pending timers. New timers added as part of the | 270 // Trigger all of the pending timers. New timers added as part of the |
267 // callbacks will be enqueued now and notified in the next spin at the | 271 // callbacks will be enqueued now and notified in the next spin at the |
268 // earliest. | 272 // earliest. |
269 _handlingCallbacks = true; | 273 _handlingCallbacks = true; |
270 try { | 274 try { |
(...skipping 22 matching lines...) Expand all Loading... | |
293 _handlingCallbacks = false; | 297 _handlingCallbacks = false; |
294 _notifyEventHandler(); | 298 _notifyEventHandler(); |
295 } | 299 } |
296 } | 300 } |
297 | 301 |
298 // Creates a receive port and registers the timer handler on that | 302 // Creates a receive port and registers the timer handler on that |
299 // receive port. | 303 // receive port. |
300 static void _createTimerHandler() { | 304 static void _createTimerHandler() { |
301 if(_receivePort == null) { | 305 if(_receivePort == null) { |
302 _receivePort = new RawReceivePort(_handleTimeout); | 306 _receivePort = new RawReceivePort(_handleTimeout); |
307 _sendPort = _receivePort.sendPort; | |
303 } | 308 } |
304 } | 309 } |
305 | 310 |
306 static void _shutdownTimerHandler() { | 311 static void _shutdownTimerHandler() { |
307 _receivePort.close(); | 312 _receivePort.close(); |
308 _receivePort = null; | 313 _receivePort = null; |
309 } | 314 } |
310 } | 315 } |
311 | 316 |
312 // Provide a closure which will allocate a Timer object to be able to hook | 317 // Provide a closure which will allocate a Timer object to be able to hook |
313 // up the Timer interface in dart:isolate with the implementation here. | 318 // up the Timer interface in dart:isolate with the implementation here. |
314 _getTimerFactoryClosure() { | 319 _getTimerFactoryClosure() { |
315 return (int milliSeconds, void callback(Timer timer), bool repeating) { | 320 return (int milliSeconds, void callback(Timer timer), bool repeating) { |
316 if (repeating) { | 321 if (repeating) { |
317 return new _Timer.periodic(milliSeconds, callback); | 322 return new _Timer.periodic(milliSeconds, callback); |
318 } | 323 } |
319 return new _Timer(milliSeconds, callback); | 324 return new _Timer(milliSeconds, callback); |
320 }; | 325 }; |
321 } | 326 } |
322 | 327 |
323 | 328 |
OLD | NEW |