Skip to content

Commit 136c273

Browse files
committed
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: nodejs#2510 PR-URL: nodejs#3510
1 parent df738ac commit 136c273

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

lib/cluster.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,10 @@ function masterInit() {
345345
* if it has disconnected, otherwise we might
346346
* still want to access it.
347347
*/
348-
if (!worker.isConnected()) removeWorker(worker);
348+
if (!worker.isConnected()) {
349+
removeHandlesForWorker(worker);
350+
removeWorker(worker);
351+
}
349352

350353
worker.suicide = !!worker.suicide;
351354
worker.state = 'dead';
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const net = require('net');
5+
const cluster = require('cluster');
6+
cluster.schedulingPolicy = cluster.SCHED_NONE;
7+
8+
if (cluster.isMaster) {
9+
var worker1, worker2;
10+
11+
worker1 = cluster.fork();
12+
worker1.on('message', common.mustCall(function() {
13+
worker2 = cluster.fork();
14+
const c = net.connect(common.PORT, common.mustCall(function() {
15+
c.unref();
16+
worker1.send('die');
17+
worker2.send('die');
18+
}));
19+
c.on('error', function(e) {
20+
// ECONNRESET is OK
21+
if (e.code !== 'ECONNRESET')
22+
throw e;
23+
});
24+
}));
25+
26+
return;
27+
}
28+
29+
var server = net.createServer({}, function(c) {
30+
c.end('bye');
31+
});
32+
33+
server.listen(common.PORT, function() {
34+
process.send('listening');
35+
});
36+
37+
process.on('message', function listener() {
38+
server.close(function() {
39+
process.exit();
40+
});
41+
});

0 commit comments

Comments
 (0)