Skip to content

Commit 47a984a

Browse files
committed
timers: prevent event loop blocking
When an interval takes as long or longer to run as its timeout setting and the roundtrip from rearm() to its deferal takes exactly 1ms, that interval can then block the event loop. This is an edge case of another recently fixed bug (which in itself was an edge case). PR-URL: #18486 Refs: #15072 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
1 parent d7894f3 commit 47a984a

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

lib/timers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ TimerWrap.prototype[kOnTimeout] = function listOnTimeout(now) {
238238
// This happens if there are more timers scheduled for later in the list.
239239
if (diff < msecs) {
240240
var timeRemaining = msecs - (TimerWrap.now() - timer._idleStart);
241-
if (timeRemaining < 0) {
241+
if (timeRemaining <= 0) {
242242
timeRemaining = 1;
243243
}
244244
this.start(timeRemaining);

test/sequential/test-timers-set-interval-excludes-callback-duration.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ const t = setInterval(() => {
99
cntr++;
1010
if (cntr === 1) {
1111
common.busyLoop(100);
12+
// ensure that the event loop passes before the second interval
13+
setImmediate(() => assert.strictEqual(cntr, 1));
1214
first = Timer.now();
1315
} else if (cntr === 2) {
1416
assert(Timer.now() - first < 100);
1517
clearInterval(t);
1618
}
1719
}, 100);
20+
const t2 = setInterval(() => {
21+
if (cntr === 2) {
22+
clearInterval(t2);
23+
}
24+
}, 100);

0 commit comments

Comments
 (0)