diff --git a/tools/run-all.js b/tools/run-all.js index 87c9d0042d..c450c63517 100644 --- a/tools/run-all.js +++ b/tools/run-all.js @@ -242,8 +242,11 @@ exports.run = function (appDir, options) { result.outcome === "wrong-release" || (result.outcome === "terminated" && result.signal === undefined && result.code === undefined)) { - runner.stop(); - fut.isResolved() || fut['return'](result); + // Allow run() to continue (and call runner.stop()) only once the + // AppRunner has processed our "return false"; otherwise we deadlock. + process.nextTick(function () { + fut.isResolved() || fut['return'](result); + }); return false; // stop restarting } runner.regenerateAppPort(); diff --git a/tools/run-app.js b/tools/run-app.js index c23f5bc870..39f5a846f9 100644 --- a/tools/run-app.js +++ b/tools/run-app.js @@ -266,11 +266,9 @@ _.extend(AppProcess.prototype, { // mongoUrl, oplogUrl, buildOptions, rootUrl, settingsFile, program, // proxy // -// To use, construct an instance of AppRunner, and then call start() -// to start it running. Call stop() at any time to shut it down and -// clean it up. You should call stop() to clean up even if you return -// false from onRunEnd(); this stops the restarting but doesn't -// destroy the AppRunner instance. +// To use, construct an instance of AppRunner, and then call start() to start it +// running. To stop it, either return false from onRunEnd, or call stop(). (But +// don't call stop() from inside onRunEnd: that causes a deadlock.) // // The 'result' argument to onRunEnd is an object with keys: // @@ -338,7 +336,8 @@ _.extend(AppRunner.prototype, { self.startFuture = new Future; self.fiber = new Fiber(function () { self._fiber(); - }).run(); + }); + self.fiber.run(); self.startFuture.wait(); self.startFuture = null; },