mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
timers: async track unref timers
When async hooks integration for Timers was introduced, it was not included in the code for unref'd or subsequently ref'd timers which means those timers only have Timerwrap hooks. PR-URL: https://github.com/nodejs/node/pull/18579 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
parent
568b6a5c9e
commit
c11cb038a1
@ -289,7 +289,7 @@ TimerWrap.prototype[kOnTimeout] = function listOnTimeout(now) {
|
||||
|
||||
// An optimization so that the try/finally only de-optimizes (since at least v8
|
||||
// 4.7) what is in this smaller function.
|
||||
function tryOnTimeout(timer) {
|
||||
function tryOnTimeout(timer, start) {
|
||||
timer._called = true;
|
||||
const timerAsyncId = (typeof timer[async_id_symbol] === 'number') ?
|
||||
timer[async_id_symbol] : null;
|
||||
@ -297,7 +297,7 @@ function tryOnTimeout(timer) {
|
||||
if (timerAsyncId !== null)
|
||||
emitBefore(timerAsyncId, timer[trigger_async_id_symbol]);
|
||||
try {
|
||||
ontimeout(timer);
|
||||
ontimeout(timer, start);
|
||||
threw = false;
|
||||
} finally {
|
||||
if (timerAsyncId !== null) {
|
||||
@ -520,7 +520,7 @@ function unrefdHandle(now) {
|
||||
try {
|
||||
// Don't attempt to call the callback if it is not a function.
|
||||
if (typeof this.owner._onTimeout === 'function') {
|
||||
ontimeout(this.owner, now);
|
||||
tryOnTimeout(this.owner, now);
|
||||
}
|
||||
} finally {
|
||||
// Make sure we clean up if the callback is no longer a function
|
||||
|
61
test/async-hooks/test-timers.setTimeout.js
Normal file
61
test/async-hooks/test-timers.setTimeout.js
Normal file
@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const tick = require('./tick');
|
||||
const initHooks = require('./init-hooks');
|
||||
const { checkInvocations } = require('./hook-checks');
|
||||
const TIMEOUT = common.platformTimeout(100);
|
||||
|
||||
const hooks = initHooks();
|
||||
hooks.enable();
|
||||
|
||||
// install first timeout
|
||||
setTimeout(common.mustCall(ontimeout), TIMEOUT);
|
||||
const as = hooks.activitiesOfTypes('Timeout');
|
||||
assert.strictEqual(as.length, 1);
|
||||
const t1 = as[0];
|
||||
assert.strictEqual(t1.type, 'Timeout');
|
||||
assert.strictEqual(typeof t1.uid, 'number');
|
||||
assert.strictEqual(typeof t1.triggerAsyncId, 'number');
|
||||
checkInvocations(t1, { init: 1 }, 't1: when first timer installed');
|
||||
|
||||
let timer;
|
||||
let t2;
|
||||
function ontimeout() {
|
||||
checkInvocations(t1, { init: 1, before: 1 }, 't1: when first timer fired');
|
||||
|
||||
setTimeout(onSecondTimeout, TIMEOUT).unref();
|
||||
const as = hooks.activitiesOfTypes('Timeout');
|
||||
t2 = as[1];
|
||||
assert.strictEqual(as.length, 2);
|
||||
checkInvocations(t1, { init: 1, before: 1 },
|
||||
't1: when second timer installed');
|
||||
checkInvocations(t2, { init: 1 },
|
||||
't2: when second timer installed');
|
||||
|
||||
timer = setTimeout(common.mustNotCall(), 2 ** 31 - 1);
|
||||
}
|
||||
|
||||
function onSecondTimeout() {
|
||||
const as = hooks.activitiesOfTypes('Timeout');
|
||||
assert.strictEqual(as.length, 3);
|
||||
checkInvocations(t1, { init: 1, before: 1, after: 1 },
|
||||
't1: when second timer fired');
|
||||
checkInvocations(t2, { init: 1, before: 1 },
|
||||
't2: when second timer fired');
|
||||
clearTimeout(timer);
|
||||
tick(2);
|
||||
}
|
||||
|
||||
process.on('exit', onexit);
|
||||
|
||||
function onexit() {
|
||||
hooks.disable();
|
||||
hooks.sanityCheck('Timeout');
|
||||
|
||||
checkInvocations(t1, { init: 1, before: 1, after: 1, destroy: 1 },
|
||||
't1: when process exits');
|
||||
checkInvocations(t2, { init: 1, before: 1, after: 1, destroy: 1 },
|
||||
't2: when process exits');
|
||||
}
|
Loading…
Reference in New Issue
Block a user