|
@ -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); |
|
|
|
|
|
}; |
|
|