Index: runtime/lib/timer_impl.dart |
diff --git a/runtime/lib/timer_impl.dart b/runtime/lib/timer_impl.dart |
index 9bb71b43ec7899af599a39369cd53e626df15bea..4a83f935a7f0a6cc9cea77c6f28f749d2b3d21ef 100644 |
--- a/runtime/lib/timer_impl.dart |
+++ b/runtime/lib/timer_impl.dart |
@@ -16,7 +16,8 @@ class _TimerHeap { |
List<_Timer> _list; |
int _used = 0; |
- _TimerHeap([int initSize = 7]) : _list = new List<_Timer>(initSize); |
+ _TimerHeap([int initSize = 7]) |
+ : _list = new List<_Timer>(initSize); |
bool get isEmpty => _used == 0; |
@@ -139,12 +140,13 @@ class _Timer implements Timer { |
static bool _handlingCallbacks = false; |
- Function _callback; // Closure to call when timer fires. null if canceled. |
- int _wakeupTime; // Expiration time. |
- final int _milliSeconds; // Duration specified at creation. |
- final bool _repeating; // Indicates periodic timers. |
- var _indexOrNext; // Index if part of the TimerHeap, link otherwise. |
- int _id; // Incrementing id to enable sorting of timers with same expiry. |
+ Function _callback; // Closure to call when timer fires. null if canceled. |
+ int _wakeupTime; // Expiration time. |
+ final int _milliSeconds; // Duration specified at creation. |
+ final bool _repeating; // Indicates periodic timers. |
+ var _indexOrNext; // Index if part of the TimerHeap, link otherwise. |
+ int _id; // Incrementing id to enable sorting of timers with same expiry. |
+ |
// Get the next available id. We accept collisions and reordering when the |
// _idCount overflows and the timers expire at the same millisecond. |
@@ -154,12 +156,16 @@ class _Timer implements Timer { |
return result; |
} |
- _Timer._internal( |
- this._callback, this._wakeupTime, this._milliSeconds, this._repeating) |
- : _id = _nextId(); |
- static Timer _createTimer( |
- void callback(Timer timer), int milliSeconds, bool repeating) { |
+ _Timer._internal(this._callback, |
+ this._wakeupTime, |
+ this._milliSeconds, |
+ this._repeating) : _id = _nextId(); |
+ |
+ |
+ static Timer _createTimer(void callback(Timer timer), |
+ int milliSeconds, |
+ bool repeating) { |
// Negative timeouts are treated as if 0 timeout. |
if (milliSeconds < 0) { |
milliSeconds = 0; |
@@ -171,32 +177,40 @@ class _Timer implements Timer { |
int now = VMLibraryHooks.timerMillisecondClock(); |
int wakeupTime = (milliSeconds == 0) ? now : (now + 1 + milliSeconds); |
- _Timer timer = |
- new _Timer._internal(callback, wakeupTime, milliSeconds, repeating); |
+ _Timer timer = new _Timer._internal(callback, |
+ wakeupTime, |
+ milliSeconds, |
+ repeating); |
// Enqueue this newly created timer in the appropriate structure and |
// notify if necessary. |
timer._enqueue(); |
return timer; |
} |
+ |
factory _Timer(int milliSeconds, void callback(Timer timer)) { |
return _createTimer(callback, milliSeconds, false); |
} |
+ |
factory _Timer.periodic(int milliSeconds, void callback(Timer timer)) { |
return _createTimer(callback, milliSeconds, true); |
} |
+ |
bool get _isInHeap => _indexOrNext is int; |
+ |
int _compareTo(_Timer other) { |
int c = _wakeupTime - other._wakeupTime; |
if (c != 0) return c; |
return _id - other._id; |
} |
+ |
bool get isActive => _callback != null; |
+ |
// Cancels a set timer. The timer is removed from the timer heap if it is a |
// non-zero timer. Zero timers are kept in the list as they need to consume |
// the corresponding pending message. |
@@ -212,6 +226,7 @@ class _Timer implements Timer { |
} |
} |
+ |
void _advanceWakeupTime() { |
// Recalculate the next wakeup time. For repeating timers with a 0 timeout |
// the next wakeup time is now. |
@@ -223,6 +238,7 @@ class _Timer implements Timer { |
} |
} |
+ |
// Adds a timer to the heap or timer list. Timers with the same wakeup time |
// are enqueued in order and notified in FIFO order. |
void _enqueue() { |
@@ -244,6 +260,7 @@ class _Timer implements Timer { |
} |
} |
+ |
// Enqeue one message for each zero timer. To be able to distinguish from |
// EventHandler messages we send a _ZERO_EVENT instead of a _TIMEOUT_EVENT. |
static void _notifyZeroHandler() { |
@@ -253,6 +270,7 @@ class _Timer implements Timer { |
_sendPort.send(_ZERO_EVENT); |
} |
+ |
// Handle the notification of a zero timer. Make sure to also execute non-zero |
// timers with a lower expiration time. |
static List _queueFromZeroEvent() { |
@@ -273,6 +291,7 @@ class _Timer implements Timer { |
return pendingTimers; |
} |
+ |
static void _notifyEventHandler() { |
if (_handlingCallbacks) { |
// While we are already handling callbacks we will not notify the event |
@@ -305,6 +324,7 @@ class _Timer implements Timer { |
} |
} |
+ |
static List _queueFromTimeoutEvent() { |
var pendingTimers = new List(); |
if (_firstZeroTimer != null) { |
@@ -332,6 +352,7 @@ class _Timer implements Timer { |
return pendingTimers; |
} |
+ |
static void _runTimers(List pendingTimers) { |
// If there are no pending timers currently reset the id space before we |
// have a chance to enqueue new timers. |
@@ -381,6 +402,7 @@ class _Timer implements Timer { |
} |
} |
+ |
static void _handleMessage(msg) { |
var pendingTimers; |
if (msg == _ZERO_EVENT) { |
@@ -388,7 +410,7 @@ class _Timer implements Timer { |
assert(pendingTimers.length > 0); |
} else { |
assert(msg == _TIMEOUT_EVENT); |
- _scheduledWakeupTime = null; // Consumed the last scheduled wakeup now. |
+ _scheduledWakeupTime = null; // Consumed the last scheduled wakeup now. |
pendingTimers = _queueFromTimeoutEvent(); |
} |
_runTimers(pendingTimers); |
@@ -397,6 +419,7 @@ class _Timer implements Timer { |
_notifyEventHandler(); |
} |
+ |
// Tell the event handler to wake this isolate at a specific time. |
static void _scheduleWakeup(int wakeupTime) { |
if (_sendPort == null) { |
@@ -406,6 +429,7 @@ class _Timer implements Timer { |
_scheduledWakeupTime = wakeupTime; |
} |
+ |
// Cancel pending wakeups in the event handler. |
static void _cancelWakeup() { |
assert(_sendPort != null); |
@@ -413,6 +437,7 @@ class _Timer implements Timer { |
_scheduledWakeupTime = null; |
} |
+ |
// Create a receive port and register a message handler for the timer |
// events. |
static void _createTimerHandler() { |
@@ -423,6 +448,7 @@ class _Timer implements Timer { |
_scheduledWakeupTime = null; |
} |
+ |
static void _shutdownTimerHandler() { |
_receivePort.close(); |
_receivePort = null; |
@@ -430,9 +456,11 @@ class _Timer implements Timer { |
_scheduledWakeupTime = null; |
} |
+ |
// The Timer factory registered with the dart:async library by the embedder. |
- static Timer _factory( |
- int milliSeconds, void callback(Timer timer), bool repeating) { |
+ static Timer _factory(int milliSeconds, |
+ void callback(Timer timer), |
+ bool repeating) { |
if (repeating) { |
return new _Timer.periodic(milliSeconds, callback); |
} |
@@ -440,6 +468,7 @@ class _Timer implements Timer { |
} |
} |
+ |
_setupHooks() { |
VMLibraryHooks.timerFactory = _Timer._factory; |
} |