node/test/parallel/test-async-hooks-http-parser-nodouble-destroy.js
Gerhard Stoebich 65ef26fdcb
async_hooks: avoid double-destroy HTTPParser
Avoid that destroy hook is invoked twice - once via `Parser::Free()`
and once again via `Parser::Reinitialize()` by clearing the async_id
in `EmitDestroy()`.

Partial backport of https://github.com/nodejs/node/pull/27477, a full
backport would require also https://github.com/nodejs/node/pull/25094
which has a dont-land-on-v10.x label on it.

Fixes: https://github.com/nodejs/node/issues/26961

Backport-PR-URL: https://github.com/nodejs/node/pull/27986
PR-URL: https://github.com/nodejs/node/pull/27477
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
2019-07-16 17:37:59 +01:00

54 lines
1.3 KiB
JavaScript

'use strict';
const common = require('../common');
const assert = require('assert');
const { createHook } = require('async_hooks');
const http = require('http');
// Regression test for https://github.com/nodejs/node/issues/19859.
// Checks that matching destroys are emitted when creating new/reusing old http
// parser instances.
const httpParsers = [];
const dupDestroys = [];
const destroyed = [];
createHook({
init(asyncId, type, triggerAsyncId, resource) {
if (type === 'HTTPPARSER') {
httpParsers.push(asyncId);
}
},
destroy(asyncId) {
if (destroyed.includes(asyncId)) {
dupDestroys.push(asyncId);
} else {
destroyed.push(asyncId);
}
}
}).enable();
const server = http.createServer((req, res) => {
res.end();
});
server.listen(common.mustCall(() => {
http.get({ port: server.address().port }, common.mustCall(() => {
server.close(common.mustCall(() => {
server.listen(common.mustCall(() => {
http.get({ port: server.address().port }, common.mustCall(() => {
server.close(common.mustCall(() => {
setTimeout(common.mustCall(verify), 200);
}));
}));
}));
}));
}));
}));
function verify() {
assert.strictEqual(httpParsers.length, 4);
assert.strictEqual(dupDestroys.length, 0);
httpParsers.forEach((id) => assert.ok(destroyed.includes(id)));
}