Browse Source

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.
v0.7.4-release
Ben Noordhuis 13 years ago
parent
commit
42281124d4
  1. 64
      lib/child_process.js
  2. 15
      src/node.js

64
lib/child_process.js

@ -167,12 +167,6 @@ exports.fork = function(modulePath, args, options) {
args = args ? args.slice(0) : []; args = args ? args.slice(0) : [];
args.unshift(modulePath); args.unshift(modulePath);
if (options.thread) {
if (!process.features.isolates) {
throw new Error('node compiled without isolate support');
}
}
if (options.stdinStream) { if (options.stdinStream) {
throw new Error('stdinStream not allowed for fork()'); throw new Error('stdinStream not allowed for fork()');
} }
@ -191,11 +185,11 @@ exports.fork = function(modulePath, args, options) {
options.env.NODE_CHANNEL_FD = 42; options.env.NODE_CHANNEL_FD = 42;
// stdin is the IPC channel. // stdin is the IPC channel.
options.stdinStream = createPipe(true); if (!options.thread) options.stdinStream = createPipe(true);
var child = spawn(process.execPath, args, options); var child = spawn(process.execPath, args, options);
setupChannel(child, options.stdinStream); if (!options.thread) setupChannel(child, options.stdinStream);
child.on('exit', function() { child.on('exit', function() {
if (child._channel) { if (child._channel) {
@ -358,7 +352,7 @@ var spawn = exports.spawn = function(file, args, options) {
envPairs.push(key + '=' + env[key]); envPairs.push(key + '=' + env[key]);
} }
var child = new ChildProcess(); var child = (options && options.thread) ? (new Isolate) : (new ChildProcess);
child.spawn({ child.spawn({
file: file, file: file,
@ -520,3 +514,55 @@ ChildProcess.prototype.kill = function(sig) {
// TODO: raise error if r == -1? // 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);
};

15
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() { startup.globalVariables = function() {

Loading…
Cancel
Save