diff options
author | cjihrig <cjihrig@gmail.com> | 2016-10-27 14:36:49 -0400 |
---|---|---|
committer | cjihrig <cjihrig@gmail.com> | 2016-11-01 20:37:57 -0400 |
commit | 2dcb7f3826a360f7cac79a58833dc4c037f67e27 (patch) | |
tree | aa533b4345de7179fa9bfec300504d8314c09930 | |
parent | f9814a2cafa6c085ab7927f2d53ca87f552fbd0c (diff) | |
download | android-node-v8-2dcb7f3826a360f7cac79a58833dc4c037f67e27.tar.gz android-node-v8-2dcb7f3826a360f7cac79a58833dc4c037f67e27.tar.bz2 android-node-v8-2dcb7f3826a360f7cac79a58833dc4c037f67e27.zip |
child_process: add public API for IPC channel
This commit adds a public channel property to ChildProcess. The
existing _channel property is aliased to the new property, with
the intention of deprecating and removing it in the future.
Fixes: https://github.com/nodejs/node/issues/9313
PR-URL: https://github.com/nodejs/node/pull/9322
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
-rw-r--r-- | doc/api/child_process.md | 11 | ||||
-rw-r--r-- | doc/api/process.md | 10 | ||||
-rw-r--r-- | lib/internal/child_process.js | 32 | ||||
-rw-r--r-- | lib/internal/process/stdio.js | 4 | ||||
-rw-r--r-- | test/parallel/test-child-process-fork-regr-gh-2847.js | 4 | ||||
-rw-r--r-- | test/parallel/test-child-process-fork.js | 2 | ||||
-rw-r--r-- | test/parallel/test-child-process-recv-handle.js | 4 | ||||
-rw-r--r-- | test/parallel/test-child-process-silent.js | 4 |
8 files changed, 51 insertions, 20 deletions
diff --git a/doc/api/child_process.md b/doc/api/child_process.md index dfe787d6f3..6fe6079d4e 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -776,6 +776,16 @@ added: v0.5.9 The `'message'` event is triggered when a child process uses [`process.send()`][] to send messages. +### child.channel +<!-- YAML +added: REPLACEME +--> + +* {Object} A pipe representing the IPC channel to the child process. + +The `child.channel` property is a reference to the child's IPC channel. If no +IPC channel currently exists, this property is `undefined`. + ### child.connected <!-- YAML added: v0.7.2 @@ -1145,6 +1155,7 @@ console.log('中文测试'); [`'error'`]: #child_process_event_error [`'exit'`]: #child_process_event_exit [`'message'`]: #child_process_event_message +[`child.channel`]: #child_process_child_channel [`child.connected`]: #child_process_child_connected [`child.disconnect()`]: #child_process_child_disconnect [`child.kill()`]: #child_process_child_kill_signal diff --git a/doc/api/process.md b/doc/api/process.md index e2b269a358..6c25fc4d6a 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -508,6 +508,16 @@ $ bash -c 'exec -a customArgv0 ./node' 'customArgv0' ``` +## process.channel +<!-- YAML +added: REPLACEME +--> + +If the Node.js process was spawned with an IPC channel (see the +[Child Process][] documentation), the `process.channel` +property is a reference to the IPC channel. If no IPC channel exists, this +property is `undefined`. + ## process.chdir(directory) <!-- YAML added: v0.1.17 diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index f79657048c..5bdc53fd19 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -69,7 +69,7 @@ const handleConversion = { // the slave should keep track of the socket message.key = socket.server._connectionKey; - var firstTime = !this._channel.sockets.send[message.key]; + var firstTime = !this.channel.sockets.send[message.key]; var socketList = getSocketList('send', this, message.key); // the server should no longer expose a .connection property @@ -409,7 +409,15 @@ ChildProcess.prototype.unref = function() { function setupChannel(target, channel) { - target._channel = channel; + target.channel = channel; + + // _channel can be deprecated in version 8 + Object.defineProperty(target, '_channel', { + get() { return target.channel; }, + set(val) { target.channel = val; }, + enumerable: true + }); + target._handleQueue = null; target._pendingHandle = null; @@ -465,7 +473,7 @@ function setupChannel(target, channel) { target.disconnect(); channel.onread = nop; channel.close(); - target._channel = null; + target.channel = null; maybeClose(target); } }; @@ -491,7 +499,7 @@ function setupChannel(target, channel) { }); // Process a pending disconnect (if any). - if (!target.connected && target._channel && !target._handleQueue) + if (!target.connected && target.channel && !target._handleQueue) target._disconnect(); return; @@ -547,7 +555,7 @@ function setupChannel(target, channel) { }; target._send = function(message, handle, options, callback) { - assert(this.connected || this._channel); + assert(this.connected || this.channel); if (message === undefined) throw new TypeError('"message" argument cannot be undefined'); @@ -667,11 +675,11 @@ function setupChannel(target, channel) { // connected will be set to false immediately when a disconnect() is // requested, even though the channel might still be alive internally to // process queued messages. The three states are distinguished as follows: - // - disconnect() never requested: _channel is not null and connected + // - disconnect() never requested: channel is not null and connected // is true - // - disconnect() requested, messages in the queue: _channel is not null + // - disconnect() requested, messages in the queue: channel is not null // and connected is false - // - disconnect() requested, channel actually disconnected: _channel is + // - disconnect() requested, channel actually disconnected: channel is // null and connected is false target.connected = true; @@ -692,10 +700,10 @@ function setupChannel(target, channel) { }; target._disconnect = function() { - assert(this._channel); + assert(this.channel); // This marks the fact that the channel is actually disconnected. - this._channel = null; + this.channel = null; if (this._pendingHandle) { this._pendingHandle.close(); @@ -729,7 +737,7 @@ function setupChannel(target, channel) { const INTERNAL_PREFIX = 'NODE_'; function handleMessage(target, message, handle) { - if (!target._channel) + if (!target.channel) return; var eventName = 'message'; @@ -860,7 +868,7 @@ function _validateStdio(stdio, sync) { function getSocketList(type, slave, key) { - var sockets = slave._channel.sockets[type]; + var sockets = slave.channel.sockets[type]; var socketList = sockets[key]; if (!socketList) { var Construct = type === 'send' ? SocketListSend : SocketListReceive; diff --git a/lib/internal/process/stdio.js b/lib/internal/process/stdio.js index c8f36c5df6..cf69657e40 100644 --- a/lib/internal/process/stdio.js +++ b/lib/internal/process/stdio.js @@ -60,9 +60,9 @@ function setupStdio() { // sitting on fd=0, in such case the pipe for this fd is already // present and creating a new one will lead to the assertion failure // in libuv. - if (process._channel && process._channel.fd === fd) { + if (process.channel && process.channel.fd === fd) { stdin = new net.Socket({ - handle: process._channel, + handle: process.channel, readable: true, writable: false }); diff --git a/test/parallel/test-child-process-fork-regr-gh-2847.js b/test/parallel/test-child-process-fork-regr-gh-2847.js index 7b4c262fbd..d985b8b4ac 100644 --- a/test/parallel/test-child-process-fork-regr-gh-2847.js +++ b/test/parallel/test-child-process-fork-regr-gh-2847.js @@ -44,8 +44,8 @@ var server = net.createServer(function(s) { } worker.process.once('close', common.mustCall(function() { - // Otherwise the crash on `_channel.fd` access may happen - assert.strictEqual(worker.process._channel, null); + // Otherwise the crash on `channel.fd` access may happen + assert.strictEqual(worker.process.channel, null); server.close(); })); diff --git a/test/parallel/test-child-process-fork.js b/test/parallel/test-child-process-fork.js index 5ae231ef03..a7d4a995a3 100644 --- a/test/parallel/test-child-process-fork.js +++ b/test/parallel/test-child-process-fork.js @@ -5,6 +5,8 @@ var fork = require('child_process').fork; var args = ['foo', 'bar']; var n = fork(common.fixturesDir + '/child-process-spawn-node.js', args); + +assert.strictEqual(n.channel, n._channel); assert.deepStrictEqual(args, ['foo', 'bar']); n.on('message', function(m) { diff --git a/test/parallel/test-child-process-recv-handle.js b/test/parallel/test-child-process-recv-handle.js index 5257c46b54..e69cd68d33 100644 --- a/test/parallel/test-child-process-recv-handle.js +++ b/test/parallel/test-child-process-recv-handle.js @@ -36,12 +36,12 @@ function master() { } function worker() { - process._channel.readStop(); // Make messages batch up. + process.channel.readStop(); // Make messages batch up. process.stdout.ref(); process.stdout.write('ok\r\n'); process.stdin.once('data', common.mustCall((data) => { assert.strictEqual(data.toString(), 'ok\r\n'); - process._channel.readStart(); + process.channel.readStart(); })); let n = 0; process.on('message', common.mustCall((msg, handle) => { diff --git a/test/parallel/test-child-process-silent.js b/test/parallel/test-child-process-silent.js index ce5e28cc32..50d4ae881a 100644 --- a/test/parallel/test-child-process-silent.js +++ b/test/parallel/test-child-process-silent.js @@ -21,8 +21,8 @@ if (process.argv[2] === 'pipe') { const child = childProcess.fork(process.argv[1], ['pipe'], {silent: true}); // Allow child process to self terminate - child._channel.close(); - child._channel = null; + child.channel.close(); + child.channel = null; child.on('exit', function() { process.exit(0); |