From 3964aedc28235a3cafa9ab9eac0267ea967d1a68 Mon Sep 17 00:00:00 2001 From: Jeremy Whitlock Date: Thu, 23 Jul 2015 18:09:21 -0600 Subject: [PATCH] timers: fix processing of nested same delay timers Whenever a timer of a specific delay creates a new timer with the same delay we currently end up processing the new timer immediately instead of scheduling the timer to run in the future. This commit basically identifies the situation, halts processing the current timer chain and reschedules the timer chain appropriately in the future. Fixes #25607 --- lib/timers.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/timers.js b/lib/timers.js index 83493eb609ee..3c5b23e389b5 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -87,13 +87,20 @@ function listOnTimeout() { var first; while (first = L.peek(list)) { - // If the previous iteration caused a timer to be added, - // update the value of "now" so that timing computations are - // done correctly. See test/simple/test-timers-blocking-callback.js - // for more information. + // Whenever a timer creates a new timer in the current list being processed + // you can end up processing the new timer immediately instead of waiting + // the scheduled time. Whenever we encounter this situation stop + // processing this list and reschedule. + // + // See: https://github.com/joyent/node/issues/25607 if (now < first._monotonicStartTime) { - now = Timer.now(); - debug('now: %d', now); + var delay = msecs - (Timer.now() - first._monotonicStartTime); + if (delay < 0) { + delay = 0; + } + debug(msecs + ' list wait because timer was added from another timer'); + list.start(delay, 0); + return; } var diff = now - first._monotonicStartTime;