From 92567283f4027940d4a4df0e7fb7444b67842ed5 Mon Sep 17 00:00:00 2001 From: Rabbit Date: Mon, 4 Apr 2022 16:43:49 +0800 Subject: [PATCH] timers: refactor internal classes to ES2015 syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/37408 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Matteo Collina Reviewed-By: Darshan Sen Reviewed-By: Michaƫl Zasso Reviewed-By: Antoine du Hamel --- lib/internal/timers.js | 235 +++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 115 deletions(-) diff --git a/lib/internal/timers.js b/lib/internal/timers.js index 7276f8eb32baed..a2a1c1e387bf6a 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -136,9 +136,6 @@ let timerListId = NumberMIN_SAFE_INTEGER; const kRefed = Symbol('refed'); -// Create a single linked list instance only once at startup -const immediateQueue = new ImmediateList(); - let nextExpiry = Infinity; let refCount = 0; @@ -161,140 +158,148 @@ function initAsyncResource(resource, type) { if (initHooksExist()) emitInit(asyncId, type, triggerAsyncId, resource); } - -// Timer constructor function. -// The entire prototype is defined in lib/timers.js -function Timeout(callback, after, args, isRepeat, isRefed) { - after *= 1; // Coalesce to number or NaN - if (!(after >= 1 && after <= TIMEOUT_MAX)) { - if (after > TIMEOUT_MAX) { - process.emitWarning(`${after} does not fit into` + - ' a 32-bit signed integer.' + - '\nTimeout duration was set to 1.', - 'TimeoutOverflowWarning'); +class Timeout { + // Timer constructor function. + // The entire prototype is defined in lib/timers.js + constructor(callback, after, args, isRepeat, isRefed) { + after *= 1; // Coalesce to number or NaN + if (!(after >= 1 && after <= TIMEOUT_MAX)) { + if (after > TIMEOUT_MAX) { + process.emitWarning(`${after} does not fit into` + + ' a 32-bit signed integer.' + + '\nTimeout duration was set to 1.', + 'TimeoutOverflowWarning'); + } + after = 1; // Schedule on next tick, follows browser behavior } - after = 1; // Schedule on next tick, follows browser behavior - } - this._idleTimeout = after; - this._idlePrev = this; - this._idleNext = this; - this._idleStart = null; - // This must be set to null first to avoid function tracking - // on the hidden class, revisit in V8 versions after 6.2 - this._onTimeout = null; - this._onTimeout = callback; - this._timerArgs = args; - this._repeat = isRepeat ? after : null; - this._destroyed = false; - - if (isRefed) - incRefCount(); - this[kRefed] = isRefed; - this[kHasPrimitive] = false; - - initAsyncResource(this, 'Timeout'); -} + this._idleTimeout = after; + this._idlePrev = this; + this._idleNext = this; + this._idleStart = null; + // This must be set to null first to avoid function tracking + // on the hidden class, revisit in V8 versions after 6.2 + this._onTimeout = null; + this._onTimeout = callback; + this._timerArgs = args; + this._repeat = isRepeat ? after : null; + this._destroyed = false; -// Make sure the linked list only shows the minimal necessary information. -Timeout.prototype[inspect.custom] = function(_, options) { - return inspect(this, { - ...options, - // Only inspect one level. - depth: 0, - // It should not recurse. - customInspect: false - }); -}; + if (isRefed) + incRefCount(); + this[kRefed] = isRefed; + this[kHasPrimitive] = false; -Timeout.prototype.refresh = function() { - if (this[kRefed]) - active(this); - else - unrefActive(this); + initAsyncResource(this, 'Timeout'); + } - return this; -}; + // Make sure the linked list only shows the minimal necessary information. + [inspect.custom](_, options) { + return inspect(this, { + ...options, + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false + }); + } -Timeout.prototype.unref = function() { - if (this[kRefed]) { - this[kRefed] = false; - if (!this._destroyed) - decRefCount(); + refresh() { + if (this[kRefed]) + active(this); + else + unrefActive(this); + + return this; } - return this; -}; -Timeout.prototype.ref = function() { - if (!this[kRefed]) { - this[kRefed] = true; - if (!this._destroyed) - incRefCount(); + unref() { + if (this[kRefed]) { + this[kRefed] = false; + if (!this._destroyed) + decRefCount(); + } + return this; } - return this; -}; -Timeout.prototype.hasRef = function() { - return this[kRefed]; -}; + ref() { + if (!this[kRefed]) { + this[kRefed] = true; + if (!this._destroyed) + incRefCount(); + } + return this; + } -function TimersList(expiry, msecs) { - this._idleNext = this; // Create the list with the linkedlist properties to - this._idlePrev = this; // Prevent any unnecessary hidden class changes. - this.expiry = expiry; - this.id = timerListId++; - this.msecs = msecs; - this.priorityQueuePosition = null; + hasRef() { + return this[kRefed]; + } } -// Make sure the linked list only shows the minimal necessary information. -TimersList.prototype[inspect.custom] = function(_, options) { - return inspect(this, { - ...options, - // Only inspect one level. - depth: 0, - // It should not recurse. - customInspect: false - }); -}; +class TimersList { + constructor(expiry, msecs) { + this._idleNext = this; // Create the list with the linkedlist properties to + this._idlePrev = this; // Prevent any unnecessary hidden class changes. + this.expiry = expiry; + this.id = timerListId++; + this.msecs = msecs; + this.priorityQueuePosition = null; + } -// A linked list for storing `setImmediate()` requests -function ImmediateList() { - this.head = null; - this.tail = null; + // Make sure the linked list only shows the minimal necessary information. + [inspect.custom](_, options) { + return inspect(this, { + ...options, + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false + }); + } } -// Appends an item to the end of the linked list, adjusting the current tail's -// next pointer and the item's previous pointer where applicable -ImmediateList.prototype.append = function(item) { - if (this.tail !== null) { - this.tail._idleNext = item; - item._idlePrev = this.tail; - } else { - this.head = item; +// A linked list for storing `setImmediate()` requests +class ImmediateList { + constructor() { + this.head = null; + this.tail = null; } - this.tail = item; -}; -// Removes an item from the linked list, adjusting the pointers of adjacent -// items and the linked list's head or tail pointers as necessary -ImmediateList.prototype.remove = function(item) { - if (item._idleNext) { - item._idleNext._idlePrev = item._idlePrev; + // Appends an item to the end of the linked list, adjusting the current tail's + // next pointer and the item's previous pointer where applicable + append(item) { + if (this.tail !== null) { + this.tail._idleNext = item; + item._idlePrev = this.tail; + } else { + this.head = item; + } + this.tail = item; } - if (item._idlePrev) { - item._idlePrev._idleNext = item._idleNext; - } + // Removes an item from the linked list, adjusting the pointers of adjacent + // items and the linked list's head or tail pointers as necessary + remove(item) { + if (item._idleNext) { + item._idleNext._idlePrev = item._idlePrev; + } - if (item === this.head) - this.head = item._idleNext; - if (item === this.tail) - this.tail = item._idlePrev; + if (item._idlePrev) { + item._idlePrev._idleNext = item._idleNext; + } - item._idleNext = null; - item._idlePrev = null; -}; + if (item === this.head) + this.head = item._idleNext; + if (item === this.tail) + this.tail = item._idlePrev; + + item._idleNext = null; + item._idlePrev = null; + } +} + +// Create a single linked list instance only once at startup +const immediateQueue = new ImmediateList(); function incRefCount() { if (refCount++ === 0)