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.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);
|
||||
};
|
||||
|
|
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() {
|
||||
|
|
Loading…
Reference in New Issue