Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndreas Madsen <amwebdk@gmail.com>2012-01-30 19:35:05 +0400
committerBert Belder <bertbelder@gmail.com>2012-01-30 19:35:27 +0400
commit836344c90ed139f2e18bbcfb18d0ff2e2e42da81 (patch)
treed06a79efa537b0968920cdb593611adeff4e1f9a /lib
parent52bd0f93bb786de028463ef56ddb1e22568584b9 (diff)
Add disconnect method to forked child processes
This disconnect method allows the child to exit gracefully. This also adds a disconnect event and connect property.
Diffstat (limited to 'lib')
-rw-r--r--lib/child_process.js43
1 files changed, 35 insertions, 8 deletions
diff --git a/lib/child_process.js b/lib/child_process.js
index 9cdf7d6eecb..4af4d4f4139 100644
--- a/lib/child_process.js
+++ b/lib/child_process.js
@@ -85,6 +85,7 @@ function setupChannel(target, channel) {
}
}
+ channel.buffering = false;
channel.onread = function(pool, offset, length, recvHandle) {
if (recvHandle && setSimultaneousAccepts) {
// Update simultaneous accepts on Windows
@@ -117,10 +118,11 @@ function setupChannel(target, channel) {
start = i + 1;
}
jsonBuffer = jsonBuffer.slice(start);
+ this.buffering = jsonBuffer.length !== 0;
} else {
- channel.close();
- target._channel = null;
+ this.buffering = false;
+ target.disconnect();
}
};
@@ -129,7 +131,7 @@ function setupChannel(target, channel) {
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) {
@@ -154,6 +156,34 @@ function setupChannel(target, channel) {
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();
}
@@ -201,11 +231,8 @@ exports.fork = function(modulePath /*, args, options*/) {
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;
};