From db908c771a55891ded4d837ce4b2435cb53e2740 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Sun, 17 Mar 2024 02:28:42 +0800 Subject: [PATCH] lib: emit listening event once when call listen twice --- 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 19d62d184a0e7d..600ea8f233401e 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1969,7 +1969,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 @@ -1998,6 +2002,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()); +}