diff --git a/doc/api/child_processes.markdown b/doc/api/child_processes.markdown index eb0a701f901..495e65e5bbd 100644 --- a/doc/api/child_processes.markdown +++ b/doc/api/child_processes.markdown @@ -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') diff --git a/lib/child_process_uv.js b/lib/child_process_uv.js index 3dbe5f11b77..916301002d6 100644 --- a/lib/child_process_uv.js +++ b/lib/child_process_uv.js @@ -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."); diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 548f9789870..ab92e5668d5 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -292,8 +292,7 @@ Handle 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 send_stream_obj = args[3]->ToObject(); assert(send_stream_obj->InternalFieldCount() > 0); StreamWrap* send_stream_wrap = static_cast(