From 14de082ab47cd461ab0cc9d205ff42d7c8f24b32 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Tue, 19 Mar 2024 23:54:59 +0800 Subject: [PATCH] lib: emit listening event once when call listen twice PR-URL: https://github.com/nodejs/node/pull/52119 Reviewed-By: Paolo Insogna Reviewed-By: Matteo Collina --- lib/net.js | 8 +++++- test/parallel/test-net-listen-twice.js | 38 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-net-listen-twice.js diff --git a/lib/net.js b/lib/net.js index c72beaaef34f65..0e8d278bdf9c7b 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1970,7 +1970,11 @@ function listenInCluster(server, address, port, addressType, const ex = new ExceptionWithHostPort(err, 'bind', address, port); return server.emit('error', ex); } - + // If there was a handle, just close it to avoid fd leak + // but it doesn't look like that's going to happen right now + if (server._handle) { + server._handle.close(); + } // Reuse primary's server handle server._handle = handle; // _listen2 sets up the listened handle, it is still named like this @@ -1999,6 +2003,8 @@ Server.prototype.listen = function(...args) { options = options._handle || options.handle || options; const flags = getFlags(options.ipv6Only); + // Refresh the id to make the previous call invalid + this._listeningId++; // (handle[, backlog][, cb]) where handle is an object with a handle if (options instanceof TCP) { this._handle = options; diff --git a/test/parallel/test-net-listen-twice.js b/test/parallel/test-net-listen-twice.js new file mode 100644 index 00000000000000..f3e3f1475b54b3 --- /dev/null +++ b/test/parallel/test-net-listen-twice.js @@ -0,0 +1,38 @@ +'use strict'; +const common = require('../common'); +const net = require('net'); +const cluster = require('cluster'); +const assert = require('assert'); + +if (cluster.isPrimary) { + const worker = cluster.fork(); + worker.on('exit', common.mustCall((code) => { + assert.ok(code === 0); + })); +} else { + const server = net.createServer(); + server.listen(); + try { + // Currently, we can call `listen` twice in cluster worker, + // if we can not call `listen` twice in the futrue, + // just skip this test. + server.listen(); + } catch (e) { + console.error(e); + process.exit(0); + } + let i = 0; + process.on('internalMessage', (msg) => { + if (msg.cmd === 'NODE_CLUSTER') { + if (++i === 2) { + setImmediate(() => { + server.close(() => { + process.disconnect(); + }); + }); + } + } + }); + // Must only call once + server.on('listening', common.mustCall()); +}