@@ -155,7 +155,7 @@ function initAsyncResource(resource, type) {
155155
156156// Timer constructor function.
157157// The entire prototype is defined in lib/timers.js
158- function Timeout ( callback , after , args , isRepeat ) {
158+ function Timeout ( callback , after , args , isRepeat , isRefed ) {
159159 after *= 1 ; // Coalesce to number or NaN
160160 if ( ! ( after >= 1 && after <= TIMEOUT_MAX ) ) {
161161 if ( after > TIMEOUT_MAX ) {
@@ -179,7 +179,9 @@ function Timeout(callback, after, args, isRepeat) {
179179 this . _repeat = isRepeat ? after : null ;
180180 this . _destroyed = false ;
181181
182- this [ kRefed ] = null ;
182+ if ( isRefed )
183+ incRefCount ( ) ;
184+ this [ kRefed ] = isRefed ;
183185
184186 initAsyncResource ( this , 'Timeout' ) ;
185187}
@@ -295,27 +297,43 @@ function decRefCount() {
295297// Schedule or re-schedule a timer.
296298// The item must have been enroll()'d first.
297299function active ( item ) {
298- insert ( item , true , getLibuvNow ( ) ) ;
300+ insertGuarded ( item , true ) ;
299301}
300302
301303// Internal APIs that need timeouts should use `unrefActive()` instead of
302304// `active()` so that they do not unnecessarily keep the process open.
303305function unrefActive ( item ) {
304- insert ( item , false , getLibuvNow ( ) ) ;
306+ insertGuarded ( item , false ) ;
305307}
306308
307309// The underlying logic for scheduling or re-scheduling a timer.
308310//
309311// Appends a timer onto the end of an existing timers list, or creates a new
310312// list if one does not already exist for the specified timeout duration.
311- function insert ( item , refed , start ) {
312- let msecs = item . _idleTimeout ;
313+ function insertGuarded ( item , refed , start ) {
314+ const msecs = item . _idleTimeout ;
313315 if ( msecs < 0 || msecs === undefined )
314316 return ;
315317
316- // Truncate so that accuracy of sub-millisecond timers is not assumed.
317- msecs = MathTrunc ( msecs ) ;
318+ insert ( item , msecs , start ) ;
319+
320+ if ( ! item [ async_id_symbol ] || item . _destroyed ) {
321+ item . _destroyed = false ;
322+ initAsyncResource ( item , 'Timeout' ) ;
323+ }
324+
325+ if ( refed === ! item [ kRefed ] ) {
326+ if ( refed )
327+ incRefCount ( ) ;
328+ else
329+ decRefCount ( ) ;
330+ }
331+ item [ kRefed ] = refed ;
332+ }
318333
334+ function insert ( item , msecs , start = getLibuvNow ( ) ) {
335+ // Truncate so that accuracy of sub-milisecond timers is not assumed.
336+ msecs = MathTrunc ( msecs ) ;
319337 item . _idleStart = start ;
320338
321339 // Use an existing list if there is one, otherwise we need to make a new one.
@@ -332,19 +350,6 @@ function insert(item, refed, start) {
332350 }
333351 }
334352
335- if ( ! item [ async_id_symbol ] || item . _destroyed ) {
336- item . _destroyed = false ;
337- initAsyncResource ( item , 'Timeout' ) ;
338- }
339-
340- if ( refed === ! item [ kRefed ] ) {
341- if ( refed )
342- incRefCount ( ) ;
343- else
344- decRefCount ( ) ;
345- }
346- item [ kRefed ] = refed ;
347-
348353 L . append ( list , item ) ;
349354}
350355
@@ -354,8 +359,8 @@ function setUnrefTimeout(callback, after) {
354359 throw new ERR_INVALID_CALLBACK ( callback ) ;
355360 }
356361
357- const timer = new Timeout ( callback , after , undefined , false ) ;
358- unrefActive ( timer ) ;
362+ const timer = new Timeout ( callback , after , undefined , false , false ) ;
363+ insert ( timer , timer . _idleTimeout ) ;
359364
360365 return timer ;
361366}
@@ -540,16 +545,14 @@ function getTimerCallbacks(runNextTicks) {
540545 } finally {
541546 if ( timer . _repeat && timer . _idleTimeout !== - 1 ) {
542547 timer . _idleTimeout = timer . _repeat ;
543- if ( start === undefined )
544- start = getLibuvNow ( ) ;
545- insert ( timer , timer [ kRefed ] , start ) ;
548+ insert ( timer , timer . _idleTimeout , start ) ;
546549 } else if ( ! timer . _idleNext && ! timer . _idlePrev ) {
547550 if ( timer [ kRefed ] )
548551 refCount -- ;
549552 timer [ kRefed ] = null ;
550553
551554 if ( destroyHooksExist ( ) && ! timer . _destroyed ) {
552- emitDestroy ( timer [ async_id_symbol ] ) ;
555+ emitDestroy ( asyncId ) ;
553556 }
554557 timer . _destroyed = true ;
555558 }
@@ -598,6 +601,7 @@ module.exports = {
598601 } ,
599602 active,
600603 unrefActive,
604+ insert,
601605 timerListMap,
602606 timerListQueue,
603607 decRefCount,
0 commit comments