Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
child_process: add isolates support
Browse files Browse the repository at this point in the history
Passing an options object with {thread:true} to .fork() or .spawn() will run the
target script in a thread instead of a separate process.
  • Loading branch information
bnoordhuis committed Jan 5, 2012
1 parent 1e73e4c commit 4228112
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
64 changes: 55 additions & 9 deletions lib/child_process.js
Expand Up @@ -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()');
}
Expand All @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 changes: 15 additions & 0 deletions src/node.js
Expand Up @@ -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() {
Expand Down

0 comments on commit 4228112

Please sign in to comment.