Skip to content

Commit d47a15b

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
1 parent 28e9a02 commit d47a15b

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

lib/cluster.js

+4-1
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';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 shotOnce = false;
10+
11+
function shoot() {
12+
var c = net.connect(common.PORT, function() {
13+
c.unref();
14+
15+
Object.keys(cluster.workers).forEach(function(id) {
16+
cluster.workers[id].send('die');
17+
});
18+
});
19+
}
20+
21+
function fork() {
22+
var worker = cluster.fork();
23+
worker.on('message', function() {
24+
if (!shotOnce) {
25+
shotOnce = true;
26+
shoot();
27+
}
28+
fork();
29+
});
30+
}
31+
fork();
32+
return;
33+
}
34+
35+
var server = net.createServer({}, function(c) {
36+
c.end();
37+
});
38+
39+
server.listen(common.PORT, function() {
40+
process.send('listening');
41+
});
42+
43+
process.on('message', function listener(msg) {
44+
if (msg === 'die') {
45+
server.close(function() {
46+
process.exit();
47+
});
48+
}
49+
});
50+

0 commit comments

Comments
 (0)