diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2012-01-06 00:42:10 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2012-01-06 00:47:14 +0100 |
commit | 42281124d4b83b0e99baf5d56b696ef242399f51 (patch) | |
tree | 62b332b31358dd80f884167ac868c77dd4ca6243 | |
parent | 1e73e4c62f14e8c68c284b20fd754523af63f157 (diff) | |
download | node-42281124d4b83b0e99baf5d56b696ef242399f51.tar.gz |
child_process: add isolates support
Passing an options object with {thread:true} to .fork() or .spawn() will run the
target script in a thread instead of a separate process.
-rw-r--r-- | lib/child_process.js | 64 | ||||
-rw-r--r-- | src/node.js | 15 |
2 files changed, 70 insertions, 9 deletions
diff --git a/lib/child_process.js b/lib/child_process.js index 2e3916660..5a3374cda 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -167,12 +167,6 @@ exports.fork = function(modulePath, args, options) { args = args ? args.slice(0) : []; args.unshift(modulePath); - if (options.thread) { - if (!process.features.isolates) { - throw new Error('node compiled without isolate support'); - } - } - if (options.stdinStream) { throw new Error('stdinStream not allowed for fork()'); } @@ -191,11 +185,11 @@ exports.fork = function(modulePath, args, options) { options.env.NODE_CHANNEL_FD = 42; // stdin is the IPC channel. - options.stdinStream = createPipe(true); + if (!options.thread) options.stdinStream = createPipe(true); var child = spawn(process.execPath, args, options); - setupChannel(child, options.stdinStream); + if (!options.thread) setupChannel(child, options.stdinStream); child.on('exit', function() { if (child._channel) { @@ -358,7 +352,7 @@ var spawn = exports.spawn = function(file, args, options) { envPairs.push(key + '=' + env[key]); } - var child = new ChildProcess(); + var child = (options && options.thread) ? (new Isolate) : (new ChildProcess); child.spawn({ file: file, @@ -520,3 +514,55 @@ ChildProcess.prototype.kill = function(sig) { // TODO: raise error if r == -1? } }; + + +// Lazy loaded. +var isolates = null; + + +function Isolate() { + if (!process.features.isolates) { + throw new Error('Compiled without isolates support.'); + } + + if (!isolates) { + isolates = process.binding('isolates'); + } + + this._handle = null; +} +inherits(Isolate, EventEmitter); // maybe inherit from ChildProcess? + + +Isolate.prototype.spawn = function(options) { + var self = this; + + if (self._handle) throw new Error('Isolate already running.'); + self._handle = isolates.create(options.args); + if (!self._handle) throw new Error('Cannot create isolate.'); + + self._handle.onmessage = function(msg) { + msg = JSON.parse('' + msg); + self.emit('message', msg); + }; + + self._handle.onexit = function() { + self._handle = null; + self.emit('exit'); + }; +}; + + +Isolate.prototype.kill = function(sig) { + if (!this._handle) throw new Error('Isolate not running.'); + // ignore silently for now, need a way to signal the other thread +}; + + +Isolate.prototype.send = function(msg) { + if (typeof msg === 'undefined') throw new TypeError('Bad argument.'); + if (!this._handle) throw new Error('Isolate not running.'); + msg = JSON.stringify(msg); + msg = new Buffer(msg); + return this._handle.send(msg); +}; diff --git a/src/node.js b/src/node.js index 1f159d6b3..1be049027 100644 --- a/src/node.js +++ b/src/node.js @@ -120,6 +120,21 @@ }); } } + + if (process.tid === 1) return; + + // isolate initialization + process.send = function(msg) { + if (typeof msg === 'undefined') throw new TypeError('Bad argument.'); + msg = JSON.stringify(msg); + msg = new Buffer(msg); + return process._send(msg); + }; + + process._onmessage = function(msg) { + msg = JSON.parse('' + msg); + process.emit('message', msg); + }; } startup.globalVariables = function() { |