See `waitpid(2)`.
+### Event: 'disconnect'
+
+This event is emitted after using the `.disconnect()` method in the parent or
+in the child. After disconnecting it is no longer possible to send messages.
+An alternative way to check if you can send messages is to see if the
+`child.connected` property is `true`.
+
### child.stdin
A `Writable Stream` that represents the child process's `stdin`.
}
});
-
+To close the IPC connection between parent and child use the
+`child.disconnect()` method. This allows the child to exit gracefully since
+there is no IPC channel keeping it alive. When calling this method the
+`disconnect` event will be emitted in both parent and child, and the
+`connected` flag will be set to `false`. Please note that you can also call
+`process.disconnect()` in the child process.
### child.kill([signal])
}
}
+ channel.buffering = false;
channel.onread = function(pool, offset, length, recvHandle) {
if (recvHandle && setSimultaneousAccepts) {
// Update simultaneous accepts on Windows
start = i + 1;
}
jsonBuffer = jsonBuffer.slice(start);
+ this.buffering = jsonBuffer.length !== 0;
} else {
- channel.close();
- target._channel = null;
+ this.buffering = false;
+ target.disconnect();
}
};
throw new TypeError('message cannot be undefined');
}
- if (!target._channel) throw new Error("channel closed");
+ if (!this.connected) throw new Error("channel closed");
// For overflow protection don't write if channel queue is too deep.
if (channel.writeQueueSize > 1024 * 1024) {
return true;
};
+ target.connected = true;
+ target.disconnect = function() {
+ if (!this.connected) return;
+
+ // do not allow messages to be written
+ this.connected = false;
+ this._channel = null;
+
+ var fired = false;
+ function finish() {
+ if (fired) return;
+ fired = true;
+
+ channel.close();
+ target.emit('disconnect');
+ }
+
+ // If a message is being read, then wait for it to complete.
+ if (channel.buffering) {
+ this.once('message', finish);
+ this.once('internalMessage', finish);
+
+ return;
+ }
+
+ finish();
+ };
+
channel.readStart();
}
if (!options.thread) setupChannel(child, options.stdinStream);
- child.on('exit', function() {
- if (child._channel) {
- child._channel.close();
- }
- });
+ // Disconnect when the child process exits.
+ child.once('exit', child.disconnect.bind(child));
return child;
};