timers: fix refresh inside callback

When `timers.refresh()` is called inside a callback, the timer would
incorrectly end up unrefed and thus not keep the event loop alive.

PR-URL: https://github.com/nodejs/node/pull/26721
Fixes: https://github.com/nodejs/node/issues/26642
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Weijia Wang <starkwang@126.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This commit is contained in:
Anatoli Papirovski 2019-03-17 11:26:01 -07:00 committed by Daniel Bevenius
parent d933cc4b02
commit 4306300b5e
2 changed files with 15 additions and 1 deletions

View File

@ -469,7 +469,7 @@ function getTimerCallbacks(runNextTicks) {
if (start === undefined)
start = getLibuvNow();
insert(timer, timer[kRefed], start);
} else {
} else if (!timer._idleNext && !timer._idlePrev) {
if (timer[kRefed])
refCount--;
timer[kRefed] = null;

View File

@ -0,0 +1,14 @@
'use strict';
const common = require('../common');
// This test checks whether a refresh called inside the callback will keep
// the event loop alive to run the timer again.
let didCall = false;
const timer = setTimeout(common.mustCall(() => {
if (!didCall) {
didCall = true;
timer.refresh();
}
}, 2), 1);