mirror of https://github.com/nodejs/node.git
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.pull/5370/head
parent
1e73e4c62f
commit
42281124d4
|
@ -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
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…
Reference in New Issue