diff --git a/lib/child_process.js b/lib/child_process.js index 2e39166608..5a3374cdaf 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 1f159d6b35..1be049027b 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() {