From bb81390db2f5fde6d34e6679cc2145f74d4f19d4 Mon Sep 17 00:00:00 2001 From: zhangzifa Date: Tue, 29 Aug 2017 17:35:56 +0800 Subject: [PATCH] timers: fix eventloop block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When there are at least 2 timers set by setInterval whose callback execution are longer than interval, the eventloop will be blocked. This commit fix the above bug. PR-URL: https://github.com/nodejs/node/pull/15072 Fixes: https://github.com/nodejs/node/issues/15068 Reviewed-By: Anna Henningsen Reviewed-By: Ruben Bridgewater Reviewed-By: Tobias Nießen Reviewed-By: James M Snell --- lib/timers.js | 2 +- .../sequential/test-timers-block-eventloop.js | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/sequential/test-timers-block-eventloop.js diff --git a/lib/timers.js b/lib/timers.js index a612f0ea4a1037..e1d13c38a73047 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -183,7 +183,7 @@ function listOnTimeout() { if (diff < msecs) { var timeRemaining = msecs - (TimerWrap.now() - timer._idleStart); if (timeRemaining < 0) { - timeRemaining = 0; + timeRemaining = 1; } this.start(timeRemaining); debug('%d list wait because diff is %d', msecs, diff); diff --git a/test/sequential/test-timers-block-eventloop.js b/test/sequential/test-timers-block-eventloop.js new file mode 100644 index 00000000000000..210cf0d80a1127 --- /dev/null +++ b/test/sequential/test-timers-block-eventloop.js @@ -0,0 +1,22 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); + +const t1 = setInterval(() => { + common.busyLoop(12); +}, 10); + +const t2 = setInterval(() => { + common.busyLoop(15); +}, 10); + +const t3 = setTimeout(common.mustNotCall('eventloop blocked!'), 100); + +setTimeout(function() { + fs.stat('./nonexistent.txt', (err, stats) => { + clearInterval(t1); + clearInterval(t2); + clearTimeout(t3); + }); +}, 50);