| 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 import 'dart:_internal' hide Symbol; | 5 import 'dart:_internal' hide Symbol; |
| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 | 139 |
| 140 static bool _handlingCallbacks = false; | 140 static bool _handlingCallbacks = false; |
| 141 | 141 |
| 142 Function _callback; // Closure to call when timer fires. null if canceled. | 142 Function _callback; // Closure to call when timer fires. null if canceled. |
| 143 int _wakeupTime; // Expiration time. | 143 int _wakeupTime; // Expiration time. |
| 144 final int _milliSeconds; // Duration specified at creation. | 144 final int _milliSeconds; // Duration specified at creation. |
| 145 final bool _repeating; // Indicates periodic timers. | 145 final bool _repeating; // Indicates periodic timers. |
| 146 var _indexOrNext; // Index if part of the TimerHeap, link otherwise. | 146 var _indexOrNext; // Index if part of the TimerHeap, link otherwise. |
| 147 int _id; // Incrementing id to enable sorting of timers with same expiry. | 147 int _id; // Incrementing id to enable sorting of timers with same expiry. |
| 148 | 148 |
| 149 int _tick = 0; // Backing for [tick], | |
| 150 | |
| 151 // Get the next available id. We accept collisions and reordering when the | 149 // Get the next available id. We accept collisions and reordering when the |
| 152 // _idCount overflows and the timers expire at the same millisecond. | 150 // _idCount overflows and the timers expire at the same millisecond. |
| 153 static int _nextId() { | 151 static int _nextId() { |
| 154 var result = _idCount; | 152 var result = _idCount; |
| 155 _idCount = (_idCount + 1) & _ID_MASK; | 153 _idCount = (_idCount + 1) & _ID_MASK; |
| 156 return result; | 154 return result; |
| 157 } | 155 } |
| 158 | 156 |
| 159 _Timer._internal( | 157 _Timer._internal( |
| 160 this._callback, this._wakeupTime, this._milliSeconds, this._repeating) | 158 this._callback, this._wakeupTime, this._milliSeconds, this._repeating) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 bool get _isInHeap => _indexOrNext is int; | 190 bool get _isInHeap => _indexOrNext is int; |
| 193 | 191 |
| 194 int _compareTo(_Timer other) { | 192 int _compareTo(_Timer other) { |
| 195 int c = _wakeupTime - other._wakeupTime; | 193 int c = _wakeupTime - other._wakeupTime; |
| 196 if (c != 0) return c; | 194 if (c != 0) return c; |
| 197 return _id - other._id; | 195 return _id - other._id; |
| 198 } | 196 } |
| 199 | 197 |
| 200 bool get isActive => _callback != null; | 198 bool get isActive => _callback != null; |
| 201 | 199 |
| 202 int get tick => _tick; | |
| 203 | |
| 204 // Cancels a set timer. The timer is removed from the timer heap if it is a | 200 // Cancels a set timer. The timer is removed from the timer heap if it is a |
| 205 // non-zero timer. Zero timers are kept in the list as they need to consume | 201 // non-zero timer. Zero timers are kept in the list as they need to consume |
| 206 // the corresponding pending message. | 202 // the corresponding pending message. |
| 207 void cancel() { | 203 void cancel() { |
| 208 _callback = null; | 204 _callback = null; |
| 209 // Only heap timers are really removed. Zero timers need to consume their | 205 // Only heap timers are really removed. Zero timers need to consume their |
| 210 // corresponding wakeup message so they are left in the queue. | 206 // corresponding wakeup message so they are left in the queue. |
| 211 if (!_isInHeap) return; | 207 if (!_isInHeap) return; |
| 212 bool update = _heap.isFirst(this); | 208 bool update = _heap.isFirst(this); |
| 213 _heap.remove(this); | 209 _heap.remove(this); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 timer._indexOrNext = null; | 356 timer._indexOrNext = null; |
| 361 | 357 |
| 362 // One of the timers in the pending_timers list can cancel | 358 // One of the timers in the pending_timers list can cancel |
| 363 // one of the later timers which will set the callback to | 359 // one of the later timers which will set the callback to |
| 364 // null. Or the pending zero timer has been canceled earlier. | 360 // null. Or the pending zero timer has been canceled earlier. |
| 365 if (timer._callback != null) { | 361 if (timer._callback != null) { |
| 366 var callback = timer._callback; | 362 var callback = timer._callback; |
| 367 if (!timer._repeating) { | 363 if (!timer._repeating) { |
| 368 // Mark timer as inactive. | 364 // Mark timer as inactive. |
| 369 timer._callback = null; | 365 timer._callback = null; |
| 370 } else if (timer._milliSeconds > 0) { | |
| 371 var ms = timer._milliSeconds; | |
| 372 int overdue = | |
| 373 VMLibraryHooks.timerMillisecondClock() - timer._wakeupTime; | |
| 374 if (overdue > ms) { | |
| 375 int missedTicks = overdue ~/ ms; | |
| 376 timer._wakeupTime += missedTicks * ms; | |
| 377 timer._tick += missedTicks; | |
| 378 } | |
| 379 } | 366 } |
| 380 timer._tick += 1; | |
| 381 | |
| 382 callback(timer); | 367 callback(timer); |
| 383 // Re-insert repeating timer if not canceled. | 368 // Re-insert repeating timer if not canceled. |
| 384 if (timer._repeating && (timer._callback != null)) { | 369 if (timer._repeating && (timer._callback != null)) { |
| 385 timer._advanceWakeupTime(); | 370 timer._advanceWakeupTime(); |
| 386 timer._enqueue(); | 371 timer._enqueue(); |
| 387 } | 372 } |
| 388 // Execute pending micro tasks. | 373 // Execute pending micro tasks. |
| 389 var immediateCallback = _removePendingImmediateCallback(); | 374 var immediateCallback = _removePendingImmediateCallback(); |
| 390 if (immediateCallback != null) { | 375 if (immediateCallback != null) { |
| 391 immediateCallback(); | 376 immediateCallback(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 if (repeating) { | 443 if (repeating) { |
| 459 return new _Timer.periodic(milliSeconds, callback); | 444 return new _Timer.periodic(milliSeconds, callback); |
| 460 } | 445 } |
| 461 return new _Timer(milliSeconds, callback); | 446 return new _Timer(milliSeconds, callback); |
| 462 } | 447 } |
| 463 } | 448 } |
| 464 | 449 |
| 465 _setupHooks() { | 450 _setupHooks() { |
| 466 VMLibraryHooks.timerFactory = _Timer._factory; | 451 VMLibraryHooks.timerFactory = _Timer._factory; |
| 467 } | 452 } |
| OLD | NEW |