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