diff --git a/lib/child_process_uv.js b/lib/child_process_uv.js index 916301002d6..a0f23edbb0b 100644 --- a/lib/child_process_uv.js +++ b/lib/child_process_uv.js @@ -95,8 +95,12 @@ function setupChannel(target, channel) { if (!target._channel) throw new Error("channel closed"); // Open up net.Socket instances - if (sendStream instanceof require('net').Socket) { + if (sendStream instanceof require('net').Socket || + sendStream instanceof require('net').Server) { sendStream = sendStream._handle; + if (!sendStream) { + throw new Error("sendStream handle not yet opened"); + } } // For overflow protection don't write if channel queue is too deep. @@ -397,8 +401,6 @@ function setStreamOption(name, index, options) { ChildProcess.prototype.spawn = function(options) { var self = this; - debugger; - setStreamOption('stdinStream', 0, options); setStreamOption('stdoutStream', 1, options); setStreamOption('stderrStream', 2, options); diff --git a/src/node.js b/src/node.js index 9615f45ea47..023132f3030 100644 --- a/src/node.js +++ b/src/node.js @@ -389,6 +389,12 @@ var fd = parseInt(process.env.NODE_CHANNEL_FD); assert(fd >= 0); var cp = NativeModule.require('child_process'); + + // Load tcp_wrap to avoid situation where we might immediately receive + // a message. + // FIXME is this really necessary? + process.binding('tcp_wrap') + cp._forkChild(fd); assert(process.send); } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index ab92e5668d5..cea1a5589ed 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -183,8 +183,6 @@ void StreamWrap::OnReadCommon(uv_stream_t* handle, ssize_t nread, uv_buf_t buf, uv_handle_type pending) { HandleScope scope; - assert(pending == UV_UNKNOWN_HANDLE); // TODO - StreamWrap* wrap = static_cast(handle->data); // We should not be getting this callback if someone as already called @@ -220,6 +218,7 @@ void StreamWrap::OnReadCommon(uv_stream_t* handle, ssize_t nread, Integer::New(nread) }; + if (pending == UV_TCP) { // Instantiate the client javascript object and handle. Local pending_obj = TCPWrap::Instantiate(); diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 3ba5ef055ca..8d36a22bca1 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -56,8 +56,14 @@ typedef class ReqWrap ConnectWrap; Local TCPWrap::Instantiate() { + // If this assert fire then process.binding('tcp_wrap') hasn't been + // called yet. + assert(tcpConstructor.IsEmpty() == false); + HandleScope scope; - return scope.Close(tcpConstructor->NewInstance()); + Local obj = tcpConstructor->NewInstance(); + + return scope.Close(obj); } diff --git a/test/fixtures/fork2.js b/test/fixtures/fork2.js new file mode 100644 index 00000000000..8958a7915aa --- /dev/null +++ b/test/fixtures/fork2.js @@ -0,0 +1,9 @@ +var assert = require('assert'); + +process.on('message', function(m, server) { + console.log('CHILD got message:', m); + assert.ok(m.hello); + assert.ok(server); + process.send({ gotHandle: true }); +}); + diff --git a/test/simple/test-child-process-fork2.js b/test/simple/test-child-process-fork2.js new file mode 100644 index 00000000000..619ba1d154b --- /dev/null +++ b/test/simple/test-child-process-fork2.js @@ -0,0 +1,27 @@ +var assert = require('assert'); +var common = require('../common'); +var fork = require('child_process').fork; +var net = require('net'); + +var n = fork(common.fixturesDir + '/fork2.js'); + +var messageCount = 0; + +var server = new net.Server(); +server.listen(common.PORT, function() { + console.log('PARENT send child server handle'); + n.send({ hello: 'world' }, server); +}); + + +n.on('message', function(m) { + console.log('PARENT got message:', m); + assert.ok(m.gotHandle); + messageCount++; + n.kill(); + server.close(); +}); + +process.on('exit', function() { + assert.equal(1, messageCount); +});