From 136c273348daa778123be542044f882540b03dbd Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 24 Oct 2015 11:51:10 -0700 Subject: [PATCH] lib: fix cluster handle leak It is possible to cause a resource leak in SharedHandle if a worker is added after all other workers have been removed. This commit fixes the leak. Fixes: https://github.com/nodejs/node/issues/2510 PR-URL: https://github.com/nodejs/node/pull/3510 --- lib/cluster.js | 5 ++- ...er-shared-worker-added-after-disconnect.js | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-cluster-shared-worker-added-after-disconnect.js diff --git a/lib/cluster.js b/lib/cluster.js index 602cc8d60b9200..eef8bd25639dd2 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -345,7 +345,10 @@ function masterInit() { * if it has disconnected, otherwise we might * still want to access it. */ - if (!worker.isConnected()) removeWorker(worker); + if (!worker.isConnected()) { + removeHandlesForWorker(worker); + removeWorker(worker); + } worker.suicide = !!worker.suicide; worker.state = 'dead'; diff --git a/test/parallel/test-cluster-shared-worker-added-after-disconnect.js b/test/parallel/test-cluster-shared-worker-added-after-disconnect.js new file mode 100644 index 00000000000000..7b8e6b307178e8 --- /dev/null +++ b/test/parallel/test-cluster-shared-worker-added-after-disconnect.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const cluster = require('cluster'); +cluster.schedulingPolicy = cluster.SCHED_NONE; + +if (cluster.isMaster) { + var worker1, worker2; + + worker1 = cluster.fork(); + worker1.on('message', common.mustCall(function() { + worker2 = cluster.fork(); + const c = net.connect(common.PORT, common.mustCall(function() { + c.unref(); + worker1.send('die'); + worker2.send('die'); + })); + c.on('error', function(e) { + // ECONNRESET is OK + if (e.code !== 'ECONNRESET') + throw e; + }); + })); + + return; +} + +var server = net.createServer({}, function(c) { + c.end('bye'); +}); + +server.listen(common.PORT, function() { + process.send('listening'); +}); + +process.on('message', function listener() { + server.close(function() { + process.exit(); + }); +});