Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4418)

Unified Diff: bin/timer_impl.dart

Issue 8973005: Fix bug 846: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bin/timer_impl.dart
===================================================================
--- bin/timer_impl.dart (revision 2499)
+++ bin/timer_impl.dart (working copy)
@@ -75,10 +75,6 @@
if (_callback !== null) {
DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
- if (entry === null) {
- _createTimerHandler();
- }
-
while (entry !== null) {
if (_wakeupTime < entry.element._wakeupTime) {
entry.prepend(this);
@@ -92,12 +88,26 @@
void _notifyEventHandler() {
+ if (_handling_callbacks) {
+ // While we are already handling callbacks we will not notify the event
+ // handler. _handleTimeout will call _notifyEventHandler once all pending
+ // timers are processed.
+ return;
+ }
+
if (_timers.firstEntry() === null) {
+ // No pending timers: Close the receive port and let the event handler
+ // know.
if (_receivePort !== null) {
EventHandler._sendData(-1, _receivePort, _NO_TIMER);
_shutdownTimerHandler();
}
} else {
+ if (_receivePort === null) {
+ // Create a receive port and register a message handler for the timer
+ // events.
+ _createTimerHandler();
+ }
EventHandler._sendData(-1,
_receivePort,
_timers.firstEntry().element._wakeupTime);
@@ -114,22 +124,34 @@
void _handleTimeout() {
int currentTime = (new Date.now()).value + _TIMER_JITTER;
+ // Collect all pending timers.
DoubleLinkedQueueEntry<_Timer> entry = _timers.firstEntry();
+ var pending_timers = new List();
while (entry !== null) {
_Timer timer = entry.element;
if (timer._wakeupTime <= currentTime) {
entry.remove();
+ pending_timers.addLast(timer);
+ entry = _timers.firstEntry();
+ } else {
+ break;
+ }
+ }
+
+ // Trigger all of the pending timers. New timers added as part of the
+ // callbacks will be enqueued now and notified in the next spin at the
+ // earliest.
+ _handling_callbacks = true;
+ try {
+ for (var timer in pending_timers) {
timer._callback(timer);
- // Always process the event with the earliest wakeupTime first.
- entry = _timers.firstEntry();
if (timer._repeating) {
timer._advanceWakeupTime();
timer._addTimerToList();
- _notifyEventHandler();
}
- } else {
- break;
}
+ } finally {
+ _handling_callbacks = false;
}
_notifyEventHandler();
}
@@ -154,6 +176,7 @@
static DoubleLinkedQueue<_Timer> _timers;
static ReceivePort _receivePort;
+ static bool _handling_callbacks = false;
var _callback;
int _milliSeconds;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698