Support sending handles to other processes

Needs test.
This commit is contained in:
Ryan Dahl 2011-10-07 01:30:26 -07:00
parent d2ab314e08
commit b413c77583
3 changed files with 16 additions and 10 deletions

View File

@ -190,8 +190,8 @@ leaner than `child_process.exec`. It has the same options.
This is a special case of the `spawn()` functionality for spawning Node
processes. In addition to having all the methods in a normal ChildProcess
instance, the returned object has a communication channel built-in. The
channel is written to with `child.send(message)` and messages are recieved
by a `'message'` event on the child.
channel is written to with `child.send(message, [sendStream])` and messages
are recieved by a `'message'` event on the child.
For example:
@ -224,6 +224,10 @@ These child Nodes are still whole new instances of V8. Assume at least 30ms
startup and 10mb memory for each new Node. That is, you cannot create many
thousands of them.
The `sendStream` option to `child.send()` is for sending a `net.Socket`
or `net.Server` object to another process. Child will receive the handle as
as second argument to the `message` event.
### child.kill(signal='SIGTERM')

View File

@ -73,7 +73,7 @@ function setupChannel(target, channel) {
var jsonBuffer = '';
channel.onread = function(pool, offset, length) {
channel.onread = function(pool, offset, length, recvStream) {
if (pool) {
for (var i = 0; i < length; i++) {
if (pool[offset + i] === LF) {
@ -82,7 +82,7 @@ function setupChannel(target, channel) {
jsonBuffer = pool.toString('ascii', i, length);
offset = i + 1;
target.emit('message', message);
target.emit('message', message, recvStream);
}
}
} else {
@ -91,11 +91,14 @@ function setupChannel(target, channel) {
}
};
target.send = function(message, fd) {
if (fd) throw new Error("not yet implemented");
target.send = function(message, sendStream) {
if (!target._channel) throw new Error("channel closed");
// Open up net.Socket instances
if (sendStream instanceof require('net').Socket) {
sendStream = sendStream._handle;
}
// For overflow protection don't write if channel queue is too deep.
if (channel.writeQueueSize > 1024 * 1024) {
return false;
@ -103,7 +106,7 @@ function setupChannel(target, channel) {
var buffer = Buffer(JSON.stringify(message) + '\n');
var writeReq = channel.write(buffer);
var writeReq = channel.write(buffer, 0, buffer.length, sendStream);
if (!writeReq) {
throw new Error(errno + " cannot write to IPC channel.");

View File

@ -292,8 +292,7 @@ Handle<Value> StreamWrap::Write(const Arguments& args) {
} else {
uv_stream_t* send_stream = NULL;
if (args.Length() > 3) {
assert(args[3]->IsObject());
if (args[3]->IsObject()) {
Local<Object> send_stream_obj = args[3]->ToObject();
assert(send_stream_obj->InternalFieldCount() > 0);
StreamWrap* send_stream_wrap = static_cast<StreamWrap*>(