diff --git a/lib/_http_client.js b/lib/_http_client.js index cb50dab1a1caa9..71dde274fc848a 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -339,7 +339,7 @@ function ClientRequest(input, options, cb) { if (typeof optsWithoutSignal.createConnection === 'function') { const oncreate = once((err, socket) => { if (err) { - process.nextTick(() => this.emit('error', err)); + process._deferTick(() => this.emit('error', err)); } else { this.onSocket(socket); } @@ -402,7 +402,7 @@ ClientRequest.prototype.abort = function abort() { return; } this.aborted = true; - process.nextTick(emitAbortNT, this); + process._deferTick(emitAbortNT, this); this.destroy(); }; @@ -723,7 +723,7 @@ function responseKeepAlive(req) { const asyncId = socket._handle ? socket._handle.getAsyncId() : undefined; // Mark this socket as available, AFTER user-added end // handlers have a chance to run. - defaultTriggerAsyncIdScope(asyncId, process.nextTick, emitFreeNT, req); + defaultTriggerAsyncIdScope(asyncId, process._deferTick, emitFreeNT, req); req.destroyed = true; if (req.res) { @@ -857,7 +857,7 @@ function listenSocketTimeout(req) { ClientRequest.prototype.onSocket = function onSocket(socket, err) { // TODO(ronag): Between here and onSocketNT the socket // has no 'error' handler. - process.nextTick(onSocketNT, this, socket, err); + process._deferTick(onSocketNT, this, socket, err); }; function onSocketNT(req, socket, err) { diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index e45ae8190e2215..4122c53c63c119 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -236,10 +236,10 @@ IncomingMessage.prototype._destroy = function _destroy(err, cb) { e = null; } cleanup(); - process.nextTick(onError, this, e || err, cb); + process._deferTick(onError, this, e || err, cb); }); } else { - process.nextTick(onError, this, err, cb); + process._deferTick(onError, this, err, cb); } }; diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 5350c08d4ce75d..2f3945c67661e6 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -895,7 +895,7 @@ OutgoingMessage.prototype.write = function write(chunk, encoding, callback) { function onError(msg, err, callback) { const triggerAsyncId = msg.socket ? msg.socket[async_id_symbol] : undefined; defaultTriggerAsyncIdScope(triggerAsyncId, - process.nextTick, + process._deferTick, emitErrorNt, msg, err, @@ -942,7 +942,7 @@ function write_(msg, chunk, encoding, callback, fromEnd) { if (!msg.destroyed) { onError(msg, err, callback); } else { - process.nextTick(callback, err); + process._deferTick(callback, err); } return false; } @@ -976,14 +976,14 @@ function write_(msg, chunk, encoding, callback, fromEnd) { } else { debug('This type of response MUST NOT have a body. ' + 'Ignoring write() calls.'); - process.nextTick(callback); + process._deferTick(callback); return true; } } if (!fromEnd && msg.socket && !msg.socket.writableCorked) { msg.socket.cork(); - process.nextTick(connectionCorkNT, msg.socket); + process._deferTick(connectionCorkNT, msg.socket); } let ret; @@ -1117,7 +1117,7 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) { } else if (!this._headerSent || this.writableLength || chunk) { this._send('', 'latin1', finish); } else { - process.nextTick(finish); + process._deferTick(finish); } if (this[kSocket]) { diff --git a/lib/_http_server.js b/lib/_http_server.js index 1222799124cc30..4d41c8bd3e62ac 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -988,7 +988,7 @@ function resOnFinish(req, res, socket, state, server) { res.detachSocket(socket); clearIncoming(req); - process.nextTick(emitCloseNT, res); + process._deferTick(emitCloseNT, res); if (res._last) { if (typeof socket.destroySoon === 'function') { diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 95f61cb9f6c289..ce510e38b58d8c 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -609,7 +609,7 @@ function TLSSocket(socket, opts) { } // Read on next tick so the caller has a chance to setup listeners - process.nextTick(initRead, this, socket); + process._deferTick(initRead, this, socket); } ObjectSetPrototypeOf(TLSSocket.prototype, net.Socket.prototype); ObjectSetPrototypeOf(TLSSocket, net.Socket); @@ -999,7 +999,7 @@ TLSSocket.prototype.renegotiate = function(options, callback) { this._handle.renegotiate(); } catch (err) { if (callback) { - process.nextTick(callback, err); + process._deferTick(callback, err); } return false; } diff --git a/lib/child_process.js b/lib/child_process.js index 449013906e93e5..5ab27fc7ffe6e3 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -783,7 +783,7 @@ function spawn(file, args, options) { if (options.signal) { const signal = options.signal; if (signal.aborted) { - process.nextTick(onAbortListener); + process._deferTick(onAbortListener); } else { addAbortListener ??= require('events').addAbortListener; const disposable = addAbortListener(signal, onAbortListener); diff --git a/lib/dgram.js b/lib/dgram.js index 8c8da1ad8856b5..0f3cf76677ffed 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -436,7 +436,7 @@ function doConnect(ex, self, ip, address, port, callback) { if (ex) { state.connectState = CONNECT_STATE_DISCONNECTED; - return process.nextTick(() => { + return process._deferTick(() => { if (callback) { self.removeListener('connect', callback); callback(ex); @@ -447,7 +447,7 @@ function doConnect(ex, self, ip, address, port, callback) { } state.connectState = CONNECT_STATE_CONNECTED; - process.nextTick(() => self.emit('connect')); + process._deferTick(() => self.emit('connect')); } @@ -680,11 +680,11 @@ function doSend(ex, self, ip, list, address, port, callback) { if (ex) { if (typeof callback === 'function') { - process.nextTick(callback, ex); + process._deferTick(callback, ex); return; } - process.nextTick(() => self.emit('error', ex)); + process._deferTick(() => self.emit('error', ex)); return; } else if (!state.handle) { return; @@ -709,14 +709,14 @@ function doSend(ex, self, ip, list, address, port, callback) { // Synchronous finish. The return code is msg_length + 1 so that we can // distinguish between synchronous success and asynchronous success. if (callback) - process.nextTick(callback, null, err - 1); + process._deferTick(callback, null, err - 1); return; } if (err && callback) { // Don't emit as error, dgram_legacy.js compatibility const ex = new ExceptionWithHostPort(err, 'send', address, port); - process.nextTick(callback, ex); + process._deferTick(callback, ex); } } @@ -747,7 +747,7 @@ Socket.prototype.close = function(callback) { state.handle.close(); state.handle = null; defaultTriggerAsyncIdScope(this[async_id_symbol], - process.nextTick, + process._deferTick, socketCloseNT, this); diff --git a/lib/diagnostics_channel.js b/lib/diagnostics_channel.js index 97a86805ce7a32..b5aa758aada302 100644 --- a/lib/diagnostics_channel.js +++ b/lib/diagnostics_channel.js @@ -82,7 +82,7 @@ function wrapStoreRun(store, data, next, transform = defaultTransform) { try { context = transform(data); } catch (err) { - process.nextTick(() => { + process._deferTick(() => { triggerUncaughtException(err, false); }); return next(); @@ -141,7 +141,7 @@ class ActiveChannel { const onMessage = this._subscribers[i]; onMessage(data, this.name); } catch (err) { - process.nextTick(() => { + process._deferTick(() => { triggerUncaughtException(err, false); }); } diff --git a/lib/dns.js b/lib/dns.js index 681f0aa3e58ecf..c3dccce76c5565 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -194,9 +194,9 @@ function lookup(hostname, options, callback) { if (!hostname) { emitInvalidHostnameWarning(hostname); if (all) { - process.nextTick(callback, null, []); + process._deferTick(callback, null, []); } else { - process.nextTick(callback, null, null, family === 6 ? 6 : 4); + process._deferTick(callback, null, null, family === 6 ? 6 : 4); } return {}; } @@ -204,10 +204,10 @@ function lookup(hostname, options, callback) { const matchedFamily = isIP(hostname); if (matchedFamily) { if (all) { - process.nextTick( + process._deferTick( callback, null, [{ address: hostname, family: matchedFamily }]); } else { - process.nextTick(callback, null, hostname, matchedFamily); + process._deferTick(callback, null, hostname, matchedFamily); } return {}; } @@ -222,7 +222,7 @@ function lookup(hostname, options, callback) { req, hostname, family, hints, verbatim, ); if (err) { - process.nextTick(callback, new DNSException(err, 'getaddrinfo', hostname)); + process._deferTick(callback, new DNSException(err, 'getaddrinfo', hostname)); return {}; } if (hasObserver('dns')) { diff --git a/lib/events.js b/lib/events.js index 3ba2484ece938f..8760d3337672b5 100644 --- a/lib/events.js +++ b/lib/events.js @@ -377,7 +377,7 @@ function addCatch(that, promise, type, args) { then.call(promise, undefined, function(err) { // The callback is called with nextTick to avoid a follow-up // rejection from this promise. - process.nextTick(emitUnhandledRejectionOrErr, that, err, type, args); + process._deferTick(emitUnhandledRejectionOrErr, that, err, type, args); }); } } catch (err) { diff --git a/lib/fs.js b/lib/fs.js index 8ddbf18cdd4865..130711f0cc103a 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -381,7 +381,7 @@ function readFile(path, options, callback) { context.signal = options.signal; } if (context.isUserFd) { - process.nextTick(function tick(context) { + process._deferTick(function tick(context) { ReflectApply(readFileAfterOpen, { context }, [null, path]); }, context); return; @@ -664,7 +664,7 @@ function read(fd, buffer, offsetOrOptions, length, position, callback) { length |= 0; if (length === 0) { - return process.nextTick(function tick() { + return process._deferTick(function tick() { callback(null, 0, buffer); }); } @@ -958,7 +958,7 @@ function writev(fd, buffers, position, callback) { callback = maybeCallback(callback || position); if (buffers.length === 0) { - process.nextTick(callback, null, 0, buffers); + process._deferTick(callback, null, 0, buffers); return; } @@ -2472,7 +2472,7 @@ function watch(filename, options, listener) { } if (options.signal) { if (options.signal.aborted) { - process.nextTick(() => watcher.close()); + process._deferTick(() => watcher.close()); } else { const listener = () => watcher.close(); kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation; @@ -2813,7 +2813,7 @@ function realpath(p, options, callback) { LOOP(); }); } else { - process.nextTick(LOOP); + process._deferTick(LOOP); } // Walk down the path, swapping out linked path parts for their real @@ -2844,7 +2844,7 @@ function realpath(p, options, callback) { isFileType(statValues, S_IFSOCK)) { return callback(null, encodeRealpathResult(p, options)); } - return process.nextTick(LOOP); + return process._deferTick(LOOP); } return fs.lstat(base, { bigint: true }, gotStat); @@ -2856,7 +2856,7 @@ function realpath(p, options, callback) { // If not a symlink, skip to the next path part if (!stats.isSymbolicLink()) { knownHard.add(base); - return process.nextTick(LOOP); + return process._deferTick(LOOP); } // Stat & read the link if not read before. @@ -2901,7 +2901,7 @@ function realpath(p, options, callback) { LOOP(); }); } else { - process.nextTick(LOOP); + process._deferTick(LOOP); } } } diff --git a/lib/inspector.js b/lib/inspector.js index e51bcf2f3cd977..b93803c4883785 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -145,7 +145,7 @@ class Session extends EventEmitter { this.#connection = null; const remainingCallbacks = this.#messageCallbacks.values(); for (const callback of remainingCallbacks) { - process.nextTick(callback, new ERR_INSPECTOR_CLOSED()); + process._deferTick(callback, new ERR_INSPECTOR_CLOSED()); } this.#messageCallbacks.clear(); this.#nextId = 1; diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 7a773d5208e250..5a65d0f03cc052 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -303,13 +303,14 @@ process.emitWarning = emitWarning; // bootstrap to make sure that any operation done before this are synchronous. // If any ticks or timers are scheduled before this they are unlikely to work. { - const { nextTick, runNextTicks } = setupTaskQueue(); + const { nextTick, deferTick, runNextTicks } = setupTaskQueue(); process.nextTick = nextTick; // Used to emulate a tick manually in the JS land. // A better name for this function would be `runNextTicks` but // it has been exposed to the process object so we keep this legacy name // TODO(joyeecheung): either remove it or make it public process._tickCallback = runNextTicks; + process._deferTick = deferTick; const { setupTimers } = internalBinding('timers'); const { diff --git a/lib/internal/bootstrap/switches/is_main_thread.js b/lib/internal/bootstrap/switches/is_main_thread.js index 3a0a2eddf92a9e..a5860e961b8498 100644 --- a/lib/internal/bootstrap/switches/is_main_thread.js +++ b/lib/internal/bootstrap/switches/is_main_thread.js @@ -118,7 +118,7 @@ function dummyDestroy(err, cb) { // The 'close' event is needed so that finished and // pipeline work correctly. if (!this._writableState.emitClose) { - process.nextTick(() => { + process._deferTick(() => { this.emit('close'); }); } @@ -258,7 +258,7 @@ function getStdin() { // once the stream implementation does so (one nextTick later), // so that the process can close down. stdin.on('pause', () => { - process.nextTick(onpause); + process._deferTick(onpause); }); function onpause() { diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 49edaba5b558e9..c619f769c7312f 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -300,7 +300,7 @@ function ChildProcess() { // Do it on nextTick so that the user has one last chance // to consume the output, if for example they only want to // start reading the data once the process exits. - process.nextTick(flushStdio, this); + process._deferTick(flushStdio, this); maybeClose(this); }; @@ -401,7 +401,7 @@ ChildProcess.prototype.spawn = function(options) { err === UV_EMFILE || err === UV_ENFILE || err === UV_ENOENT) { - process.nextTick(onErrorNT, this, err); + process._deferTick(onErrorNT, this, err); // There is no point in continuing when we've hit EMFILE or ENFILE // because we won't be able to set up the stdio file descriptors. @@ -420,7 +420,7 @@ ChildProcess.prototype.spawn = function(options) { this._handle = null; throw new ErrnoException(err, 'spawn'); } else { - process.nextTick(onSpawnNT, this); + process._deferTick(onSpawnNT, this); } this.pid = this._handle.pid; @@ -718,7 +718,7 @@ function setupChannel(target, channel, serializationMode) { target.on('newListener', function() { - process.nextTick(() => { + process._deferTick(() => { if (!target.channel || !target.listenerCount('message')) return; @@ -753,9 +753,9 @@ function setupChannel(target, channel, serializationMode) { } const ex = new ERR_IPC_CHANNEL_CLOSED(); if (typeof callback === 'function') { - process.nextTick(callback, ex); + process._deferTick(callback, ex); } else { - process.nextTick(() => this.emit('error', ex)); + process._deferTick(() => this.emit('error', ex)); } return false; }; @@ -868,7 +868,7 @@ function setupChannel(target, channel, serializationMode) { }; control.refCounted(); } else if (typeof callback === 'function') { - process.nextTick(callback, null); + process._deferTick(callback, null); } } else { // Cleanup handle on error @@ -878,9 +878,9 @@ function setupChannel(target, channel, serializationMode) { if (!options.swallowErrors) { const ex = new ErrnoException(err, 'write'); if (typeof callback === 'function') { - process.nextTick(callback, ex); + process._deferTick(callback, ex); } else { - process.nextTick(() => this.emit('error', ex)); + process._deferTick(() => this.emit('error', ex)); } } } @@ -943,7 +943,7 @@ function setupChannel(target, channel, serializationMode) { return; } - process.nextTick(finish); + process._deferTick(finish); }; function emit(event, message, handle) { @@ -964,7 +964,7 @@ function setupChannel(target, channel, serializationMode) { const eventName = (internal ? 'internalMessage' : 'message'); - process.nextTick(emit, eventName, message, handle); + process._deferTick(emit, eventName, message, handle); } channel.readStart(); diff --git a/lib/internal/cluster/primary.js b/lib/internal/cluster/primary.js index 945f440cd19797..ca9cfdaa338141 100644 --- a/lib/internal/cluster/primary.js +++ b/lib/internal/cluster/primary.js @@ -83,14 +83,14 @@ cluster.setupPrimary = function(options) { cluster.settings = settings; if (initialized === true) - return process.nextTick(setupSettingsNT, settings); + return process._deferTick(setupSettingsNT, settings); initialized = true; schedulingPolicy = cluster.schedulingPolicy; // Freeze policy. assert(schedulingPolicy === SCHED_NONE || schedulingPolicy === SCHED_RR, `Bad cluster.schedulingPolicy: ${schedulingPolicy}`); - process.nextTick(setupSettingsNT, settings); + process._deferTick(setupSettingsNT, settings); process.on('internalMessage', (message) => { if (message.cmd !== 'NODE_DEBUG_ENABLED') @@ -211,7 +211,7 @@ cluster.fork = function(env) { }); worker.process.on('internalMessage', internal(worker, onmessage)); - process.nextTick(emitForkNT, worker); + process._deferTick(emitForkNT, worker); cluster.workers[worker.id] = worker; return worker; }; @@ -224,7 +224,7 @@ cluster.disconnect = function(cb) { const workers = ObjectKeys(cluster.workers); if (workers.length === 0) { - process.nextTick(() => intercom.emit('disconnect')); + process._deferTick(() => intercom.emit('disconnect')); } else { for (const worker of ObjectValues(cluster.workers)) { if (worker.isConnected()) { diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index 0533216969bc8e..ec342eaca7889d 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -262,7 +262,7 @@ function randomInt(min, max, callback) { if (x < randLimit) { const n = (x % range) + min; if (isSync) return n; - process.nextTick(callback, undefined, n); + process._deferTick(callback, undefined, n); return; } } diff --git a/lib/internal/debugger/inspect.js b/lib/internal/debugger/inspect.js index 5e93699f8ba078..a602adc42ea871 100644 --- a/lib/internal/debugger/inspect.js +++ b/lib/internal/debugger/inspect.js @@ -182,7 +182,7 @@ class NodeInspector { this.repl.on('exit', exitCodeZero); this.paused = false; } catch (error) { - process.nextTick(() => { throw error; }); + process._deferTick(() => { throw error; }); } })(); } @@ -203,7 +203,7 @@ class NodeInspector { } this.stdin.resume(); } catch (error) { - process.nextTick(() => { throw error; }); + process._deferTick(() => { throw error; }); } })(); } diff --git a/lib/internal/debugger/inspect_repl.js b/lib/internal/debugger/inspect_repl.js index b4f454152dc438..cf607aa889cb26 100644 --- a/lib/internal/debugger/inspect_repl.js +++ b/lib/internal/debugger/inspect_repl.js @@ -1098,7 +1098,7 @@ function createRepl(inspector) { exitDebugRepl = () => { // Restore all listeners - process.nextTick(() => { + process._deferTick(() => { ArrayPrototypeForEach(listeners, (listener) => { repl.on('SIGINT', listener); }); diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 4c67453fea4c59..24cdeb6c0feb25 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -1093,7 +1093,7 @@ function addCatch(promise) { } function emitUncaughtException(err) { - process.nextTick(() => { throw err; }); + process._deferTick(() => { throw err; }); } function makeEventHandler(handler) { diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 82c6c1bd780fba..81c4aa6669ab11 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -106,7 +106,7 @@ class Dir { } if (maybeSync) - process.nextTick(callback, null, dirent); + process._deferTick(callback, null, dirent); else callback(null, dirent); return; @@ -117,7 +117,7 @@ class Dir { const req = new FSReqCallback(); req.oncomplete = (err, result) => { - process.nextTick(() => { + process._deferTick(() => { const queue = this[kDirOperationQueue]; this[kDirOperationQueue] = null; for (const op of queue) op(); @@ -237,7 +237,7 @@ class Dir { validateFunction(callback, 'callback'); if (this[kDirClosed] === true) { - process.nextTick(callback, new ERR_DIR_CLOSED()); + process._deferTick(callback, new ERR_DIR_CLOSED()); return; } diff --git a/lib/internal/fs/read/context.js b/lib/internal/fs/read/context.js index b1a5d6ae03e953..b233c75307aedd 100644 --- a/lib/internal/fs/read/context.js +++ b/lib/internal/fs/read/context.js @@ -111,7 +111,7 @@ class ReadFileContext { close(err) { if (this.isUserFd) { - process.nextTick(function tick(context) { + process._deferTick(function tick(context) { ReflectApply(readFileAfterClose, { context }, [null]); }, this); return; diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index 43f06d0104de61..9aede51eb37fd2 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -534,7 +534,7 @@ WriteStream.prototype._destroy = function(err, cb) { WriteStream.prototype.close = function(cb) { if (cb) { if (this.closed) { - process.nextTick(cb); + process._deferTick(cb); return; } this.on('close', cb); diff --git a/lib/internal/fs/watchers.js b/lib/internal/fs/watchers.js index f5ecc15159f457..490e7b0e625d61 100644 --- a/lib/internal/fs/watchers.js +++ b/lib/internal/fs/watchers.js @@ -144,7 +144,7 @@ StatWatcher.prototype.stop = function() { return; defaultTriggerAsyncIdScope(this._handle.getAsyncId(), - process.nextTick, + process._deferTick, emitStop, this); this._handle.close(); @@ -274,7 +274,7 @@ FSWatcher.prototype.close = function() { } this._handle.close(); this._handle = null; // Make the handle garbage collectable. - process.nextTick(emitCloseNT, this); + process._deferTick(emitCloseNT, this); }; FSWatcher.prototype.ref = function() { diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index 7bf079900c652f..cfcbd1737529be 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -406,7 +406,7 @@ class Http2ServerRequest extends Readable { state.didRead = true; this[kStream].on('data', onStreamData); } else { - process.nextTick(resumeStream, this[kStream]); + process._deferTick(resumeStream, this[kStream]); } } @@ -740,7 +740,7 @@ class Http2ServerResponse extends Stream { if (err) { if (typeof cb === 'function') - process.nextTick(cb, err); + process._deferTick(cb, err); this.destroy(err); return false; } @@ -766,7 +766,7 @@ class Http2ServerResponse extends Stream { if ((state.closed || state.ending) && state.headRequest === stream.headRequest) { if (typeof cb === 'function') { - process.nextTick(cb); + process._deferTick(cb); } return this; } @@ -812,7 +812,7 @@ class Http2ServerResponse extends Stream { createPushResponse(headers, callback) { validateFunction(callback, 'callback'); if (this[kState].closed) { - process.nextTick(callback, new ERR_HTTP2_INVALID_STREAM()); + process._deferTick(callback, new ERR_HTTP2_INVALID_STREAM()); return; } this[kStream].pushStream(headers, {}, (err, stream, headers, options) => { diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index e6056c395cda68..5a0a92e5e2b000 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -384,7 +384,7 @@ function onSessionHeaders(handle, id, cat, flags, headers, sensitiveHeaders) { } if (endOfStream) stream[kState].endAfterHeaders = true; - process.nextTick(emit, session, 'stream', stream, obj, flags, headers); + process._deferTick(emit, session, 'stream', stream, obj, flags, headers); } else { let event; const status = obj[HTTP2_HEADER_STATUS]; @@ -410,7 +410,7 @@ function onSessionHeaders(handle, id, cat, flags, headers, sensitiveHeaders) { originSet.delete(stream[kOrigin]); } debugStream(id, type, "emitting stream '%s' event", event); - process.nextTick(emit, stream, event, obj, flags, headers); + process._deferTick(emit, stream, event, obj, flags, headers); } if (endOfStream) { stream.push(null); @@ -1019,7 +1019,7 @@ function setupHandle(socket, type, options) { // core will check for session.destroyed before progressing, this // ensures that those at l`east get cleared out. if (this.destroyed) { - process.nextTick(emit, this, 'connect', this, socket); + process._deferTick(emit, this, 'connect', this, socket); return; } @@ -1080,7 +1080,7 @@ function setupHandle(socket, type, options) { ReflectApply(this.origin, this, options.origins); } - process.nextTick(emit, this, 'connect', this, socket); + process._deferTick(emit, this, 'connect', this, socket); } // Emits a close event followed by an error event if err is truthy. Used @@ -1135,7 +1135,7 @@ function finishSessionClose(session, error) { } }); } else { - process.nextTick(emitClose, session, error); + process._deferTick(emitClose, session, error); } } @@ -1281,7 +1281,7 @@ class Http2Session extends EventEmitter { // Process data on the next tick - a remoteSettings handler may be attached. // https://github.com/nodejs/node/issues/35981 - process.nextTick(() => { + process._deferTick(() => { // Socket already has some buffered data - emulate receiving it // https://github.com/nodejs/node/issues/35475 // https://github.com/nodejs/node/issues/34532 @@ -1392,7 +1392,7 @@ class Http2Session extends EventEmitter { const cb = pingCallback(callback); if (this.connecting || this.closed) { - process.nextTick(cb, false, 0.0, payload); + process._deferTick(cb, false, 0.0, payload); return; } @@ -2173,7 +2173,7 @@ class Http2Stream extends Duplex { }; // Shutdown write stream right after last chunk is sent // so final DATA frame can include END_STREAM flag - process.nextTick(() => { + process._deferTick(() => { if (writeCallbackErr || !this._writableState.ending || this._writableState.buffered.length || @@ -2739,7 +2739,7 @@ class ServerHttp2Stream extends Http2Stream { err = new NghttpError(ret); break; } - process.nextTick(callback, err); + process._deferTick(callback, err); return; } @@ -2755,7 +2755,7 @@ class ServerHttp2Stream extends Http2Stream { if (headRequest) stream[kState].flags |= STREAM_FLAGS_HEAD_REQUEST; - process.nextTick(callback, null, stream, headers, 0); + process._deferTick(callback, null, stream, headers, 0); } // Initiate a response on this Http2Stream diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js index a6aee73f468b08..b4972132ee1491 100644 --- a/lib/internal/js_stream_socket.js +++ b/lib/internal/js_stream_socket.js @@ -151,7 +151,7 @@ class JSStreamSocket extends Socket { const handle = this._handle; assert(handle !== null); - process.nextTick(() => { + process._deferTick(() => { // Ensure that write is dispatched asynchronously. this.stream.end(() => { this.finishShutdown(handle, 0); diff --git a/lib/internal/main/inspect.js b/lib/internal/main/inspect.js index a60e4aa40b9605..2ed6d87acf7c74 100644 --- a/lib/internal/main/inspect.js +++ b/lib/internal/main/inspect.js @@ -13,6 +13,6 @@ prepareMainThreadExecution(); markBootstrapComplete(); // Start the debugger agent. -process.nextTick(() => { +process._deferTick(() => { require('internal/debugger/inspect').start(); }); diff --git a/lib/internal/process/promises.js b/lib/internal/process/promises.js index d80ce1ef764a00..7e9f10d06ef75a 100644 --- a/lib/internal/process/promises.js +++ b/lib/internal/process/promises.js @@ -135,7 +135,7 @@ const multipleResolvesDeprecate = deprecate( function resolveError(type, promise, reason) { // We have to wrap this in a next tick. Otherwise the error could be caught by // the executed promise. - process.nextTick(() => { + process._deferTick(() => { if (process.emit('multipleResolves', type, promise, reason)) { multipleResolvesDeprecate(); } diff --git a/lib/internal/process/task_queues.js b/lib/internal/process/task_queues.js index bcb5eef841dd00..adff7f63d867b1 100644 --- a/lib/internal/process/task_queues.js +++ b/lib/internal/process/task_queues.js @@ -52,7 +52,8 @@ function setHasTickScheduled(value) { tickInfo[kHasTickScheduled] = value ? 1 : 0; } -const queue = new FixedQueue(); +const nextQueue = new FixedQueue(); +const deferQueue = new FixedQueue(); // Should be in sync with RunNextTicksNative in node_task_queue.cc function runNextTicks() { @@ -67,7 +68,7 @@ function runNextTicks() { function processTicksAndRejections() { let tock; do { - while ((tock = queue.shift()) !== null) { + while ((tock = nextQueue.shift()) !== null) { const asyncId = tock[async_id_symbol]; emitBefore(asyncId, tock[trigger_async_id_symbol], tock); @@ -93,6 +94,31 @@ function processTicksAndRejections() { emitAfter(asyncId); } runMicrotasks(); + while ((tock = deferQueue.shift()) !== null) { + const asyncId = tock[async_id_symbol]; + emitBefore(asyncId, tock[trigger_async_id_symbol], tock); + + try { + const callback = tock.callback; + if (tock.args === undefined) { + callback(); + } else { + const args = tock.args; + switch (args.length) { + case 1: callback(args[0]); break; + case 2: callback(args[0], args[1]); break; + case 3: callback(args[0], args[1], args[2]); break; + case 4: callback(args[0], args[1], args[2], args[3]); break; + default: callback(...args); + } + } + } finally { + if (destroyHooksExist()) + emitDestroy(asyncId); + } + + emitAfter(asyncId); + } } while (!queue.isEmpty() || processPromiseRejections()); setHasTickScheduled(false); setHasRejectionToWarn(false); @@ -118,7 +144,43 @@ function nextTick(callback) { args[i - 1] = arguments[i]; } - if (queue.isEmpty()) + if (nextQueue.isEmpty()) + setHasTickScheduled(true); + const asyncId = newAsyncId(); + const triggerAsyncId = getDefaultTriggerAsyncId(); + const tickObject = { + [async_id_symbol]: asyncId, + [trigger_async_id_symbol]: triggerAsyncId, + callback, + args, + }; + if (initHooksExist()) + emitInit(asyncId, 'TickObject', triggerAsyncId, tickObject); + nextQueue.push(tickObject); +} + + +// `deferTick()` will not enqueue any callback when the process is about to +// exit since the callback would not have a chance to be executed. +function deferTick(callback) { + validateFunction(callback, 'callback'); + + if (process._exiting) + return; + + let args; + switch (arguments.length) { + case 1: break; + case 2: args = [arguments[1]]; break; + case 3: args = [arguments[1], arguments[2]]; break; + case 4: args = [arguments[1], arguments[2], arguments[3]]; break; + default: + args = new Array(arguments.length - 1); + for (let i = 1; i < arguments.length; i++) + args[i - 1] = arguments[i]; + } + + if (deferQueue.isEmpty()) setHasTickScheduled(true); const asyncId = newAsyncId(); const triggerAsyncId = getDefaultTriggerAsyncId(); @@ -130,7 +192,7 @@ function nextTick(callback) { }; if (initHooksExist()) emitInit(asyncId, 'TickObject', triggerAsyncId, tickObject); - queue.push(tickObject); + deferQueue.push(tickObject); } function runMicrotask() { @@ -166,6 +228,7 @@ module.exports = { setTickCallback(processTicksAndRejections); return { nextTick, + deferTick, runNextTicks, }; }, diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index 9e1e6f7a6a2dde..a71fb976c49835 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -181,12 +181,12 @@ function emitWarning(warning, type, code, ctor) { if (process.throwDeprecation) { // Delay throwing the error to guarantee that all former warnings were // properly logged. - return process.nextTick(() => { + return process._deferTick(() => { throw warning; }); } } - process.nextTick(doEmitWarning, warning); + process._deferTick(doEmitWarning, warning); } function emitWarningSync(warning, type, code, ctor) { diff --git a/lib/internal/readline/callbacks.js b/lib/internal/readline/callbacks.js index 692048c9157199..236993ac53d37f 100644 --- a/lib/internal/readline/callbacks.js +++ b/lib/internal/readline/callbacks.js @@ -44,7 +44,7 @@ function cursorTo(stream, x, y, callback) { if (NumberIsNaN(y)) throw new ERR_INVALID_ARG_VALUE('y', y); if (stream == null || (typeof x !== 'number' && typeof y !== 'number')) { - if (typeof callback === 'function') process.nextTick(callback, null); + if (typeof callback === 'function') process._deferTick(callback, null); return true; } @@ -64,7 +64,7 @@ function moveCursor(stream, dx, dy, callback) { } if (stream == null || !(dx || dy)) { - if (typeof callback === 'function') process.nextTick(callback, null); + if (typeof callback === 'function') process._deferTick(callback, null); return true; } @@ -98,7 +98,7 @@ function clearLine(stream, dir, callback) { } if (stream === null || stream === undefined) { - if (typeof callback === 'function') process.nextTick(callback, null); + if (typeof callback === 'function') process._deferTick(callback, null); return true; } @@ -117,7 +117,7 @@ function clearScreenDown(stream, callback) { } if (stream === null || stream === undefined) { - if (typeof callback === 'function') process.nextTick(callback, null); + if (typeof callback === 'function') process._deferTick(callback, null); return true; } diff --git a/lib/internal/readline/interface.js b/lib/internal/readline/interface.js index f7f06674ef7c41..6081ee5940c697 100644 --- a/lib/internal/readline/interface.js +++ b/lib/internal/readline/interface.js @@ -324,7 +324,7 @@ function InterfaceConstructor(input, output, completer, terminal) { if (signal) { const onAborted = () => self.close(); if (signal.aborted) { - process.nextTick(onAborted); + process._deferTick(onAborted); } else { const disposable = EventEmitter.addAbortListener(signal, onAborted); self.once('close', disposable[SymbolDispose]); diff --git a/lib/internal/readline/promises.js b/lib/internal/readline/promises.js index 1a0c7b4c809d47..63f981f80b0282 100644 --- a/lib/internal/readline/promises.js +++ b/lib/internal/readline/promises.js @@ -44,7 +44,7 @@ class Readline { if (y != null) validateInteger(y, 'y'); const data = y == null ? CSI`${x + 1}G` : CSI`${y + 1};${x + 1}H`; - if (this.#autoCommit) process.nextTick(() => this.#stream.write(data)); + if (this.#autoCommit) process._deferTick(() => this.#stream.write(data)); else ArrayPrototypePush(this.#todo, data); return this; @@ -74,7 +74,7 @@ class Readline { } else if (dy > 0) { data += CSI`${dy}B`; } - if (this.#autoCommit) process.nextTick(() => this.#stream.write(data)); + if (this.#autoCommit) process._deferTick(() => this.#stream.write(data)); else ArrayPrototypePush(this.#todo, data); } return this; @@ -95,7 +95,7 @@ class Readline { dir < 0 ? kClearToLineBeginning : dir > 0 ? kClearToLineEnd : kClearLine; - if (this.#autoCommit) process.nextTick(() => this.#stream.write(data)); + if (this.#autoCommit) process._deferTick(() => this.#stream.write(data)); else ArrayPrototypePush(this.#todo, data); return this; } @@ -106,7 +106,7 @@ class Readline { */ clearScreenDown() { if (this.#autoCommit) { - process.nextTick(() => this.#stream.write(kClearScreenDown)); + process._deferTick(() => this.#stream.write(kClearScreenDown)); } else { ArrayPrototypePush(this.#todo, kClearScreenDown); } diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index 28802cae5eff32..c0debb97390171 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -112,9 +112,9 @@ function _destroy(self, err, cb) { } if (err) { - process.nextTick(emitErrorCloseNT, self, err); + process._deferTick(emitErrorCloseNT, self, err); } else { - process.nextTick(emitCloseNT, self); + process._deferTick(emitCloseNT, self); } } try { @@ -233,7 +233,7 @@ function errorOrDestroy(stream, err, sync) { r.errored = err; } if (sync) { - process.nextTick(emitErrorNT, stream, err); + process._deferTick(emitErrorNT, stream, err); } else { emitErrorNT(stream, err); } @@ -262,7 +262,7 @@ function construct(stream, cb) { return; } - process.nextTick(constructNT, stream); + process._deferTick(constructNT, stream); } function constructNT(stream) { @@ -291,16 +291,16 @@ function constructNT(stream) { } else if (err) { errorOrDestroy(stream, err, true); } else { - process.nextTick(emitConstructNT, stream); + process._deferTick(emitConstructNT, stream); } } try { stream._construct((err) => { - process.nextTick(onConstruct, err); + process._deferTick(onConstruct, err); }); } catch (err) { - process.nextTick(onConstruct, err); + process._deferTick(onConstruct, err); } } @@ -318,7 +318,7 @@ function emitCloseLegacy(stream) { function emitErrorCloseLegacy(stream, err) { stream.emit('error', err); - process.nextTick(emitCloseLegacy, stream); + process._deferTick(emitCloseLegacy, stream); } // Normalize destroy for legacy. @@ -345,9 +345,9 @@ function destroyer(stream, err) { // TODO: Don't lose err? stream.close(); } else if (err) { - process.nextTick(emitErrorCloseLegacy, stream, err); + process._deferTick(emitErrorCloseLegacy, stream, err); } else { - process.nextTick(emitCloseLegacy, stream); + process._deferTick(emitCloseLegacy, stream); } if (!stream.destroyed) { diff --git a/lib/internal/streams/duplexify.js b/lib/internal/streams/duplexify.js index 2503b531519066..6d379f067de4c3 100644 --- a/lib/internal/streams/duplexify.js +++ b/lib/internal/streams/duplexify.js @@ -126,9 +126,9 @@ module.exports = function duplexify(body, name) { final(async () => { try { await promise; - process.nextTick(cb, null); + process._deferTick(cb, null); } catch (err) { - process.nextTick(cb, err); + process._deferTick(cb, err); } }); }, @@ -217,7 +217,7 @@ function fromAsyncGen(fn) { const _promise = promise; promise = null; const { chunk, done, cb } = await _promise; - process.nextTick(cb); + process._deferTick(cb); if (done) return; if (signal.aborted) throw new AbortError(undefined, { cause: signal.reason }); diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 663222e3149bad..038ffb1b0a6415 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -206,25 +206,25 @@ function eos(stream, options, callback) { stream.on('close', onclose); if (closed) { - process.nextTick(onclose); + process._deferTick(onclose); } else if (wState?.errorEmitted || rState?.errorEmitted) { if (!willEmitClose) { - process.nextTick(onclosed); + process._deferTick(onclosed); } } else if ( !readable && (!willEmitClose || isReadable(stream)) && (writableFinished || isWritable(stream) === false) ) { - process.nextTick(onclosed); + process._deferTick(onclosed); } else if ( !writable && (!willEmitClose || isWritable(stream)) && (readableFinished || isReadable(stream) === false) ) { - process.nextTick(onclosed); + process._deferTick(onclosed); } else if ((rState && stream.req && stream.aborted)) { - process.nextTick(onclosed); + process._deferTick(onclosed); } const cleanup = () => { @@ -252,7 +252,7 @@ function eos(stream, options, callback) { new AbortError(undefined, { cause: options.signal.reason })); }; if (options.signal.aborted) { - process.nextTick(abort); + process._deferTick(abort); } else { addAbortListener ??= require('events').addAbortListener; const disposable = addAbortListener(options.signal, abort); @@ -276,7 +276,7 @@ function eosWeb(stream, options, callback) { callback.call(stream, new AbortError(undefined, { cause: options.signal.reason })); }; if (options.signal.aborted) { - process.nextTick(abort); + process._deferTick(abort); } else { addAbortListener ??= require('events').addAbortListener; const disposable = addAbortListener(options.signal, abort); @@ -289,7 +289,7 @@ function eosWeb(stream, options, callback) { } const resolverFn = (...args) => { if (!isAborted) { - process.nextTick(() => callback.apply(stream, args)); + process._deferTick(() => callback.apply(stream, args)); } }; PromisePrototypeThen( diff --git a/lib/internal/streams/from.js b/lib/internal/streams/from.js index aa7e031d3e48d4..d43a3c90d8f3db 100644 --- a/lib/internal/streams/from.js +++ b/lib/internal/streams/from.js @@ -66,8 +66,8 @@ function from(Readable, iterable, opts) { readable._destroy = function(error, cb) { PromisePrototypeThen( close(error), - () => process.nextTick(cb, error), // nextTick is here in case cb throws - (e) => process.nextTick(cb, e || error), + () => process._deferTick(cb, error), // nextTick is here in case cb throws + (e) => process._deferTick(cb, e || error), ); }; diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index aac7f65f0404d8..3d8a59cec4aa75 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -244,7 +244,7 @@ function pipelineImpl(streams, callback, opts) { if (!error) { lastStreamCleanup.forEach((fn) => fn()); } - process.nextTick(callback, error, value); + process._deferTick(callback, error, value); } } @@ -337,10 +337,10 @@ function pipelineImpl(streams, callback, opts) { if (end) { pt.end(); } - process.nextTick(finish); + process._deferTick(finish); }, (err) => { pt.destroy(err); - process.nextTick(finish, err); + process._deferTick(finish, err); }, ); } else if (isIterable(ret, true)) { @@ -403,7 +403,7 @@ function pipelineImpl(streams, callback, opts) { } if (signal?.aborted || outerSignal?.aborted) { - process.nextTick(abort); + process._deferTick(abort); } return ret; @@ -431,7 +431,7 @@ function pipe(src, dst, finish, { end }) { } if (isReadableFinished(src)) { // End the destination if the source has already ended. - process.nextTick(endFn); + process._deferTick(endFn); } else { src.once('end', endFn); } diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index 3800399c82ad62..ec3d47783cc4aa 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -821,7 +821,7 @@ function emitReadable(stream) { if ((state[kState] & kEmittedReadable) === 0) { debug('emitReadable', (state[kState] & kFlowing) !== 0); state[kState] |= kEmittedReadable; - process.nextTick(emitReadable_, stream); + process._deferTick(emitReadable_, stream); } } @@ -855,7 +855,7 @@ function emitReadable_(stream) { function maybeReadMore(stream, state) { if ((state[kState] & (kReadingMore | kConstructed)) === kConstructed) { state[kState] |= kReadingMore; - process.nextTick(maybeReadMore_, stream, state); + process._deferTick(maybeReadMore_, stream, state); } } @@ -926,7 +926,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { const endFn = doEnd ? onend : unpipe; if ((state[kState] & kEndEmitted) !== 0) - process.nextTick(endFn); + process._deferTick(endFn); else src.once('end', endFn); @@ -1145,7 +1145,7 @@ Readable.prototype.on = function(ev, fn) { if (state.length) { emitReadable(this); } else if ((state[kState] & kReading) === 0) { - process.nextTick(nReadingNextTick, this); + process._deferTick(nReadingNextTick, this); } } } @@ -1167,7 +1167,7 @@ Readable.prototype.removeListener = function(ev, fn) { // support once('readable', fn) cycles. This means that calling // resume within the same tick will have no // effect. - process.nextTick(updateReadableListening, this); + process._deferTick(updateReadableListening, this); } else if (ev === 'data' && this.listenerCount('data') === 0) { state[kState] &= ~kDataListening; } @@ -1187,7 +1187,7 @@ Readable.prototype.removeAllListeners = function(ev) { // support once('readable', fn) cycles. This means that calling // resume within the same tick will have no // effect. - process.nextTick(updateReadableListening, this); + process._deferTick(updateReadableListening, this); } return res; @@ -1245,7 +1245,7 @@ Readable.prototype.resume = function() { function resume(stream, state) { if ((state[kState] & kResumeScheduled) === 0) { state[kState] |= kResumeScheduled; - process.nextTick(resume_, stream, state); + process._deferTick(resume_, stream, state); } } @@ -1683,7 +1683,7 @@ function endReadable(stream) { debug('endReadable'); if ((state[kState] & kEndEmitted) === 0) { state[kState] |= kEnded; - process.nextTick(endReadableNT, state, stream); + process._deferTick(endReadableNT, state, stream); } } @@ -1696,7 +1696,7 @@ function endReadableNT(state, stream) { stream.emit('end'); if (stream.writable && stream.allowHalfOpen === false) { - process.nextTick(endWritableNT, stream); + process._deferTick(endWritableNT, stream); } else if (state.autoDestroy) { // In case of duplex streams we need a way to detect // if the writable side is ready for autoDestroy as well. diff --git a/lib/internal/streams/transform.js b/lib/internal/streams/transform.js index 42e1adda618b87..389d2896c030ff 100644 --- a/lib/internal/streams/transform.js +++ b/lib/internal/streams/transform.js @@ -182,7 +182,7 @@ Transform.prototype._write = function(chunk, encoding, callback) { // If user has called this.push(null) we have to // delay the callback to properly progate the new // state. - process.nextTick(callback); + process._deferTick(callback); } else if ( wState.ended || // Backwards compat. length === rState.length || // Backwards compat. diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js index 0dbf56d7a69ca9..36b9e9f05e6f51 100644 --- a/lib/internal/streams/writable.js +++ b/lib/internal/streams/writable.js @@ -484,7 +484,7 @@ function _write(stream, chunk, encoding, cb) { } if (err) { - process.nextTick(cb, err); + process._deferTick(cb, err); errorOrDestroy(stream, err, true); return err; } @@ -635,7 +635,7 @@ function onwrite(stream, er) { } if (sync) { - process.nextTick(onwriteError, stream, state, er, cb); + process._deferTick(onwriteError, stream, state, er, cb); } else { onwriteError(stream, state, er, cb); } @@ -654,7 +654,7 @@ function onwrite(stream, er) { // memory allocations. if (cb === nop) { if ((state[kState] & kAfterWritePending) === 0 && needTick) { - process.nextTick(afterWrite, stream, state, 1, cb); + process._deferTick(afterWrite, stream, state, 1, cb); state[kState] |= kAfterWritePending; } else { state.pendingcb--; @@ -667,7 +667,7 @@ function onwrite(stream, er) { state[kAfterWriteTickInfoValue].count++; } else if (needTick) { state[kAfterWriteTickInfoValue] = { count: 1, cb, stream, state }; - process.nextTick(afterWriteTick, state[kAfterWriteTickInfoValue]); + process._deferTick(afterWriteTick, state[kAfterWriteTickInfoValue]); state[kState] |= (kAfterWritePending | kAfterWriteTickInfo); } else { state.pendingcb--; @@ -843,11 +843,11 @@ Writable.prototype.end = function(chunk, encoding, cb) { if (typeof cb === 'function') { if (err) { - process.nextTick(cb, err); + process._deferTick(cb, err); } else if ((state[kState] & kErrored) !== 0) { - process.nextTick(cb, state[kErroredValue]); + process._deferTick(cb, state[kErroredValue]); } else if ((state[kState] & kFinished) !== 0) { - process.nextTick(cb, null); + process._deferTick(cb, null); } else { state[kState] |= kOnFinished; state[kOnFinishedValue] ??= []; @@ -890,7 +890,7 @@ function onFinish(stream, state, err) { // Some streams assume 'finish' will be emitted // asynchronously relative to _final callback. state.pendingcb++; - process.nextTick(finish, stream, state); + process._deferTick(finish, stream, state); } } @@ -922,7 +922,7 @@ function finishMaybe(stream, state, sync) { if (state.pendingcb === 0) { if (sync) { state.pendingcb++; - process.nextTick((stream, state) => { + process._deferTick((stream, state) => { if (needFinish(state)) { finish(stream, state); } else { @@ -1107,7 +1107,7 @@ Writable.prototype.destroy = function(err, cb) { // Invoke pending callbacks. if ((state[kState] & (kBuffered | kOnFinished)) !== 0 && (state[kState] & kDestroyed) === 0) { - process.nextTick(errorBuffer, state); + process._deferTick(errorBuffer, state); } destroy.call(this, err, cb); diff --git a/lib/internal/tls/secure-pair.js b/lib/internal/tls/secure-pair.js index 7e0a2f992a82b8..ed65d1efd3a33e 100644 --- a/lib/internal/tls/secure-pair.js +++ b/lib/internal/tls/secure-pair.js @@ -31,7 +31,7 @@ class DuplexSocket extends Duplex { _write(chunk, encoding, callback) { if (chunk.length === 0) { - process.nextTick(callback); + process._deferTick(callback); } else { this[kOtherSide].push(chunk); this[kOtherSide][kCallback] = callback; diff --git a/lib/internal/webstreams/adapters.js b/lib/internal/webstreams/adapters.js index cffa549eafd683..afe2afab2199fe 100644 --- a/lib/internal/webstreams/adapters.js +++ b/lib/internal/webstreams/adapters.js @@ -286,7 +286,7 @@ function newStreamWritableFromWritableStream(writableStream, options = kEmptyObj // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => destroy(writable, error)); + process._deferTick(() => destroy(writable, error)); } } @@ -348,7 +348,7 @@ function newStreamWritableFromWritableStream(writableStream, options = kEmptyObj // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => { throw error; }); + process._deferTick(() => { throw error; }); } } @@ -380,7 +380,7 @@ function newStreamWritableFromWritableStream(writableStream, options = kEmptyObj // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => destroy(writable, error)); + process._deferTick(() => destroy(writable, error)); } } @@ -562,7 +562,7 @@ function newStreamReadableFromReadableStream(readableStream, options = kEmptyObj // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => { throw error; }); + process._deferTick(() => { throw error; }); } } @@ -709,7 +709,7 @@ function newStreamDuplexFromReadableWritablePair(pair = kEmptyObject, options = // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => destroy(duplex, error)); + process._deferTick(() => destroy(duplex, error)); } } @@ -771,7 +771,7 @@ function newStreamDuplexFromReadableWritablePair(pair = kEmptyObject, options = // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => destroy(duplex, error)); + process._deferTick(() => destroy(duplex, error)); } } @@ -806,7 +806,7 @@ function newStreamDuplexFromReadableWritablePair(pair = kEmptyObject, options = // thrown we don't want those to cause an unhandled // rejection. Let's just escape the promise and // handle it separately. - process.nextTick(() => { throw error; }); + process._deferTick(() => { throw error; }); } } diff --git a/lib/internal/webstreams/readablestream.js b/lib/internal/webstreams/readablestream.js index 4af209349341d1..abf57b0841ca6f 100644 --- a/lib/internal/webstreams/readablestream.js +++ b/lib/internal/webstreams/readablestream.js @@ -1611,10 +1611,10 @@ function readableStreamDefaultTee(stream, cloneForBranch2) { }); }, [kClose]() { - // The `process.nextTick()` is not part of the spec. + // The `process._deferTick()` is not part of the spec. // This approach was needed to avoid a race condition working with esm // Further information, see: https://github.com/nodejs/node/issues/39758 - process.nextTick(() => { + process._deferTick(() => { reading = false; if (!canceled1) readableStreamDefaultControllerClose(branch1[kState].controller); diff --git a/lib/internal/worker.js b/lib/internal/worker.js index b58cbe56d01703..0b039c4105b246 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -290,7 +290,7 @@ class Worker extends EventEmitter { // Actually start the new thread now that everything is in place. this[kHandle].startThread(); - process.nextTick(() => process.emit('worker', this)); + process._deferTick(() => process.emit('worker', this)); if (workerThreadsChannel.hasSubscribers) { workerThreadsChannel.publish({ worker: this, diff --git a/lib/net.js b/lib/net.js index fa470dbb060455..4c4d01e86c0c0d 100644 --- a/lib/net.js +++ b/lib/net.js @@ -562,7 +562,7 @@ function writeAfterFIN(chunk, encoding, cb) { { code: 'EPIPE' }, ); if (typeof cb === 'function') { - defaultTriggerAsyncIdScope(this[async_id_symbol], process.nextTick, cb, er); + defaultTriggerAsyncIdScope(this[async_id_symbol], process._deferTick, cb, er); } this.destroy(er); @@ -833,7 +833,7 @@ Socket.prototype._destroy = function(exception, cb) { cb(exception); } else { cb(exception); - process.nextTick(emitCloseNT, this); + process._deferTick(emitCloseNT, this); } if (this._server) { @@ -1317,7 +1317,7 @@ function lookupAndConnect(self, options) { // If host is an IP, skip performing a lookup const addressType = isIP(host); if (addressType) { - defaultTriggerAsyncIdScope(self[async_id_symbol], process.nextTick, () => { + defaultTriggerAsyncIdScope(self[async_id_symbol], process._deferTick, () => { if (self.connecting) defaultTriggerAsyncIdScope( self[async_id_symbol], @@ -1384,15 +1384,15 @@ function lookupAndConnect(self, options) { // net.createConnection() creates a net.Socket object and immediately // calls net.Socket.connect() on it (that's us). There are no event // listeners registered yet so defer the error event to the next tick. - process.nextTick(connectErrorNT, self, err); + process._deferTick(connectErrorNT, self, err); } else if (!isIP(ip)) { err = new ERR_INVALID_IP_ADDRESS(ip); - process.nextTick(connectErrorNT, self, err); + process._deferTick(connectErrorNT, self, err); } else if (addressType !== 4 && addressType !== 6) { err = new ERR_INVALID_ADDRESS_FAMILY(addressType, options.host, options.port); - process.nextTick(connectErrorNT, self, err); + process._deferTick(connectErrorNT, self, err); } else { self._unrefTimer(); defaultTriggerAsyncIdScope( @@ -1421,7 +1421,7 @@ function lookupAndConnectMultiple( // net.createConnection() creates a net.Socket object and immediately // calls net.Socket.connect() on it (that's us). There are no event // listeners registered yet so defer the error event to the next tick. - process.nextTick(connectErrorNT, self, err); + process._deferTick(connectErrorNT, self, err); return; } @@ -1458,12 +1458,12 @@ function lookupAndConnectMultiple( if (!isIP(firstIp)) { err = new ERR_INVALID_IP_ADDRESS(firstIp); - process.nextTick(connectErrorNT, self, err); + process._deferTick(connectErrorNT, self, err); } else if (firstAddressType !== 4 && firstAddressType !== 6) { err = new ERR_INVALID_ADDRESS_FAMILY(firstAddressType, options.host, options.port); - process.nextTick(connectErrorNT, self, err); + process._deferTick(connectErrorNT, self, err); } return; @@ -1625,9 +1625,9 @@ function addClientAbortSignalOption(self, options) { } if (signal.aborted) { - process.nextTick(onAbort); + process._deferTick(onAbort); } else { - process.nextTick(() => { + process._deferTick(() => { disposable = EventEmitter.addAbortListener(signal, onAbort); }); } @@ -1718,7 +1718,7 @@ function addServerAbortSignalOption(self, options) { self.close(); }; if (signal.aborted) { - process.nextTick(onAborted); + process._deferTick(onAborted); } else { const disposable = EventEmitter.addAbortListener(signal, onAborted); self.once('close', disposable[SymbolDispose]); @@ -1874,7 +1874,7 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) { if (typeof rval === 'number') { const error = new UVExceptionWithHostPort(rval, 'listen', address, port); - process.nextTick(emitErrorNT, this, error); + process._deferTick(emitErrorNT, this, error); return; } this._handle = rval; @@ -1894,7 +1894,7 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) { this._handle.close(); this._handle = null; defaultTriggerAsyncIdScope(this[async_id_symbol], - process.nextTick, + process._deferTick, emitErrorNT, this, ex); @@ -1909,7 +1909,7 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) { this.unref(); defaultTriggerAsyncIdScope(this[async_id_symbol], - process.nextTick, + process._deferTick, emitListeningNT, this); } @@ -2200,7 +2200,7 @@ Server.prototype.getConnections = function(cb) { function end(err, connections) { defaultTriggerAsyncIdScope(self[async_id_symbol], - process.nextTick, + process._deferTick, cb, err, connections); @@ -2289,7 +2289,7 @@ Server.prototype._emitCloseIfDrained = function() { } defaultTriggerAsyncIdScope(this[async_id_symbol], - process.nextTick, + process._deferTick, emitCloseNT, this); }; diff --git a/lib/repl.js b/lib/repl.js index 3effdc7bb82d41..1f182e76a7d773 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -743,7 +743,7 @@ function REPLServer(prompt, if (options[kStandaloneREPL] && process.listenerCount('uncaughtException') !== 0) { - process.nextTick(() => { + process._deferTick(() => { process.emit('uncaughtException', e); self.clearBufferedCommand(); self.lines.level = []; @@ -1087,7 +1087,7 @@ REPLServer.prototype.close = function close() { return; } - process.nextTick(() => + process._deferTick(() => ReflectApply(Interface.prototype.close, this, []), ); }; diff --git a/lib/util.js b/lib/util.js index 13a437c9318d05..e0b8b77652f081 100644 --- a/lib/util.js +++ b/lib/util.js @@ -312,8 +312,8 @@ function callbackify(original) { // In true node style we process the callback on `nextTick` with all the // implications (stack, `uncaughtException`, `async_hooks`) ReflectApply(original, this, args) - .then((ret) => process.nextTick(cb, null, ret), - (rej) => process.nextTick(callbackifyOnRejected, rej, cb)); + .then((ret) => process._deferTick(cb, null, ret), + (rej) => process._deferTick(callbackifyOnRejected, rej, cb)); } const descriptors = ObjectGetOwnPropertyDescriptors(original); diff --git a/lib/zlib.js b/lib/zlib.js index 3766938f6bc7bb..e9451111789ebe 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -390,7 +390,7 @@ ZlibBase.prototype.flush = function(kind, callback) { if (this.writableFinished) { if (callback) - process.nextTick(callback); + process._deferTick(callback); } else if (this.writableEnded) { if (callback) this.once('end', callback); @@ -521,7 +521,7 @@ function processChunkSync(self, chunk, flushFlag) { function processChunk(self, chunk, flushFlag, cb) { const handle = self._handle; - if (!handle) return process.nextTick(cb); + if (!handle) return process._deferTick(cb); handle.buffer = chunk; handle.cb = cb; @@ -723,7 +723,7 @@ Zlib.prototype.params = function params(level, strategy, callback) { FunctionPrototypeBind(paramsAfterFlushCallback, this, level, strategy, callback)); } else { - process.nextTick(callback); + process._deferTick(callback); } };