◐ Shell
clean mode source ↗

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

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

186186

const kBufferedCommandSymbol = Symbol('bufferedCommand');

187187

const kLoadingSymbol = Symbol('loading');

188188189-

let addedNewListener = false;

189+

function processNewListener(event, listener) {

190+

if (event === 'uncaughtException' &&

191+

process.domain &&

192+

listener.name !== 'domainUncaughtExceptionClear' &&

193+

domainSet.has(process.domain)) {

194+

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

195+

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

196+

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

197+

// that contains an error.

198+

throw new ERR_INVALID_REPL_INPUT(

199+

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

200+

}

201+

}

202+203+

let processNewListenerUseCount = 0;

204+

function addProcessNewListener() {

205+

if (processNewListenerUseCount++ === 0) {

206+

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

207+

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

208+

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

209+

process.prependListener('newListener', processNewListener);

210+

}

211+

}

212+213+

function removeProcessNewListener() {

214+

if (--processNewListenerUseCount === 0) {

215+

process.removeListener('newListener', processNewListener);

216+

}

217+

}

190218191219

fixReplRequire(module);

192220

@@ -327,24 +355,9 @@ function REPLServer(prompt,

327355

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

328356

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

329357

module.exports.repl = this;

330-

} else if (!addedNewListener) {

331-

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

332-

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

333-

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

334-

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

335-

if (event === 'uncaughtException' &&

336-

process.domain &&

337-

listener.name !== 'domainUncaughtExceptionClear' &&

338-

domainSet.has(process.domain)) {

339-

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

340-

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

341-

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

342-

// that contains an error.

343-

throw new ERR_INVALID_REPL_INPUT(

344-

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

345-

}

346-

});

347-

addedNewListener = true;

358+

} else {

359+

addProcessNewListener();

360+

this.once('exit', removeProcessNewListener);

348361

}

349362350363

domainSet.add(this._domain);