diff options
author | Anatoli Papirovski <apapirovski@mac.com> | 2018-01-31 13:37:01 -0500 |
---|---|---|
committer | Anatoli Papirovski <apapirovski@mac.com> | 2018-02-04 11:04:12 -0500 |
commit | 47a984ada005d4db150b3d0ebd71b560411e7470 (patch) | |
tree | e53a6863b264a3d009319df175e63ec6eb0727e1 | |
parent | d7894f3969fd3932eef57d9759f01282c7d76aa5 (diff) | |
download | android-node-v8-47a984ada005d4db150b3d0ebd71b560411e7470.tar.gz android-node-v8-47a984ada005d4db150b3d0ebd71b560411e7470.tar.bz2 android-node-v8-47a984ada005d4db150b3d0ebd71b560411e7470.zip |
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: https://github.com/nodejs/node/pull/18486
Refs: https://github.com/nodejs/node/pull/15072
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
-rw-r--r-- | lib/timers.js | 2 | ||||
-rw-r--r-- | test/sequential/test-timers-set-interval-excludes-callback-duration.js | 7 |
2 files changed, 8 insertions, 1 deletions
diff --git a/lib/timers.js b/lib/timers.js index 734c58712d..79fc432dcd 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -238,7 +238,7 @@ TimerWrap.prototype[kOnTimeout] = function listOnTimeout(now) { // This happens if there are more timers scheduled for later in the list. if (diff < msecs) { var timeRemaining = msecs - (TimerWrap.now() - timer._idleStart); - if (timeRemaining < 0) { + if (timeRemaining <= 0) { timeRemaining = 1; } this.start(timeRemaining); diff --git a/test/sequential/test-timers-set-interval-excludes-callback-duration.js b/test/sequential/test-timers-set-interval-excludes-callback-duration.js index d47659d7b3..cb60d7e452 100644 --- a/test/sequential/test-timers-set-interval-excludes-callback-duration.js +++ b/test/sequential/test-timers-set-interval-excludes-callback-duration.js @@ -9,9 +9,16 @@ const t = setInterval(() => { cntr++; if (cntr === 1) { common.busyLoop(100); + // ensure that the event loop passes before the second interval + setImmediate(() => assert.strictEqual(cntr, 1)); first = Timer.now(); } else if (cntr === 2) { assert(Timer.now() - first < 100); clearInterval(t); } }, 100); +const t2 = setInterval(() => { + if (cntr === 2) { + clearInterval(t2); + } +}, 100); |