◐ Shell
clean mode source ↗

repl: keep reference count for `process.on('newListener')` · nodejs/node@999bf22

@@ -183,7 +183,35 @@ const domainSet = new SafeWeakSet();

183183

const kBufferedCommandSymbol = Symbol('bufferedCommand');

184184

const kLoadingSymbol = Symbol('loading');

185185186-

let addedNewListener = false;

186+

function processNewListener(event, listener) {

187+

if (event === 'uncaughtException' &&

188+

process.domain &&

189+

listener.name !== 'domainUncaughtExceptionClear' &&

190+

domainSet.has(process.domain)) {

191+

// Throw an error so that the event will not be added and the current

192+

// domain takes over. That way the user is notified about the error

193+

// and the current code evaluation is stopped, just as any other code

194+

// that contains an error.

195+

throw new ERR_INVALID_REPL_INPUT(

196+

'Listeners for `uncaughtException` cannot be used in the REPL');

197+

}

198+

}

199+200+

let processNewListenerUseCount = 0;

201+

function addProcessNewListener() {

202+

if (processNewListenerUseCount++ === 0) {

203+

// Add this listener only once and use a WeakSet that contains the REPLs

204+

// domains. Otherwise we'd have to add a single listener to each REPL

205+

// instance and that could trigger the `MaxListenersExceededWarning`.

206+

process.prependListener('newListener', processNewListener);

207+

}

208+

}

209+210+

function removeProcessNewListener() {

211+

if (--processNewListenerUseCount === 0) {

212+

process.removeListener('newListener', processNewListener);

213+

}

214+

}

187215188216

fixReplRequire(module);

189217

@@ -337,24 +365,9 @@ class REPLServer extends Interface {

337365

// It is possible to introspect the running REPL accessing this variable

338366

// from inside the REPL. This is useful for anyone working on the REPL.

339367

module.exports.repl = this;

340-

} else if (!addedNewListener) {

341-

// Add this listener only once and use a WeakSet that contains the REPLs

342-

// domains. Otherwise we'd have to add a single listener to each REPL

343-

// instance and that could trigger the `MaxListenersExceededWarning`.

344-

process.prependListener('newListener', (event, listener) => {

345-

if (event === 'uncaughtException' &&

346-

process.domain &&

347-

listener.name !== 'domainUncaughtExceptionClear' &&

348-

domainSet.has(process.domain)) {

349-

// Throw an error so that the event will not be added and the current

350-

// domain takes over. That way the user is notified about the error

351-

// and the current code evaluation is stopped, just as any other code

352-

// that contains an error.

353-

throw new ERR_INVALID_REPL_INPUT(

354-

'Listeners for `uncaughtException` cannot be used in the REPL');

355-

}

356-

});

357-

addedNewListener = true;

368+

} else {

369+

addProcessNewListener();

370+

this.once('exit', removeProcessNewListener);

358371

}

359372360373

domainSet.add(this._domain);