Browse Source

child_process: acknowledge sent handles

Fix race-condition when multiple handles are sent and SCM_RIGHTS
messages are gets merged by OS by avoiding sending multiple handles at
once!

fix #4885
v0.10.3-release
Fedor Indutny 12 years ago
committed by isaacs
parent
commit
5902bc45c5
  1. 29
      lib/child_process.js

29
lib/child_process.js

@ -24,6 +24,7 @@ var EventEmitter = require('events').EventEmitter;
var net = require('net');
var dgram = require('dgram');
var Process = process.binding('process_wrap').Process;
var assert = require('assert');
var util = require('util');
var constants; // if (!constants) constants = process.binding('constants');
@ -321,6 +322,7 @@ function handleMessage(target, message, handle) {
function setupChannel(target, channel) {
target._channel = channel;
target._handleQueue = null;
var decoder = new StringDecoder('utf8');
var jsonBuffer = '';
@ -358,8 +360,22 @@ function setupChannel(target, channel) {
// handlers will go through this
target.on('internalMessage', function(message, handle) {
// Once acknowledged - continue sending handles.
if (message.cmd === 'NODE_HANDLE_ACK') {
assert(Array.isArray(target._handleQueue));
var queue = target._handleQueue;
target._handleQueue = null;
queue.forEach(function(args) {
target.send(args.message, args.handle);
});
return;
}
if (message.cmd !== 'NODE_HANDLE') return;
// Acknowledge handle receival.
target.send({ cmd: 'NODE_HANDLE_ACK' });
var obj = handleConversion[message.type];
// Update simultaneous accepts on Windows
@ -389,6 +405,7 @@ function setupChannel(target, channel) {
// this message will be handled by an internalMessage event handler
message = {
cmd: 'NODE_HANDLE',
type: null,
msg: message
};
@ -407,6 +424,12 @@ function setupChannel(target, channel) {
throw new TypeError("This handle type can't be sent");
}
// Queue-up message and handle if we haven't received ACK yet.
if (this._handleQueue) {
this._handleQueue.push({ message: message.msg, handle: handle });
return;
}
var obj = handleConversion[message.type];
// convert TCP object to native handle object
@ -416,6 +439,10 @@ function setupChannel(target, channel) {
if (obj.simultaneousAccepts) {
net._setSimultaneousAccepts(handle);
}
} else if (this._handleQueue) {
// Queue request anyway to avoid out-of-order messages.
this._handleQueue.push({ message: message, handle: null });
return;
}
var string = JSON.stringify(message) + '\n';
@ -426,6 +453,8 @@ function setupChannel(target, channel) {
'write',
'cannot write to IPC channel.');
this.emit('error', er);
} else if (handle && !this._handleQueue) {
this._handleQueue = [];
}
if (obj && obj.postSend) {

Loading…
Cancel
Save