| 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;
|
| }
|
|
|