@ -373,3 +373,111 @@ exports.clearImmediate = function(immediate) {
process . _ needImmediateCallback = false ;
process . _ needImmediateCallback = false ;
}
}
} ;
} ;
// Internal APIs that need timeouts should use timers._unrefActive isntead of
// timers.active as internal timeouts shouldn't hold the loop open
var unrefList , unrefTimer ;
function unrefTimeout ( ) {
var now = Date . now ( ) ;
debug ( 'unrefTimer fired' ) ;
var first ;
while ( first = L . peek ( unrefList ) ) {
var diff = now - first . _ idleStart ;
if ( diff < first . _ idleTimeout ) {
diff = first . _ idleTimeout - diff ;
unrefTimer . start ( diff , 0 ) ;
unrefTimer . when = now + diff ;
debug ( 'unrefTimer rescheudling for later' ) ;
return ;
}
L . remove ( first ) ;
var domain = first . domain ;
if ( ! first . _ onTimeout ) continue ;
if ( domain && domain . _ disposed ) continue ;
try {
if ( domain ) domain . enter ( ) ;
var threw = true ;
debug ( 'unreftimer firing timeout' ) ;
first . _ onTimeout ( ) ;
threw = false ;
if ( domain ) domain . exit ( ) ;
} finally {
if ( threw ) process . nextTick ( unrefTimeout ) ;
}
}
debug ( 'unrefList is empty' ) ;
unrefTimer . when = - 1 ;
}
exports . _ unrefActive = function ( item ) {
var msecs = item . _ idleTimeout ;
if ( ! msecs || msecs < 0 ) return ;
assert ( msecs >= 0 ) ;
L . remove ( item ) ;
if ( ! unrefList ) {
debug ( 'unrefList initialized' ) ;
unrefList = { } ;
L . init ( unrefList ) ;
debug ( 'unrefTimer initialized' ) ;
unrefTimer = new Timer ( ) ;
unrefTimer . unref ( ) ;
unrefTimer . when = - 1 ;
unrefTimer . ontimeout = unrefTimeout ;
}
var now = Date . now ( ) ;
item . _ idleStart = now ;
if ( L . isEmpty ( unrefList ) ) {
debug ( 'unrefList empty' ) ;
L . append ( unrefList , item ) ;
unrefTimer . start ( msecs , 0 ) ;
unrefTimer . when = now + msecs ;
debug ( 'unrefTimer scheduled' ) ;
return ;
}
var when = now + msecs ;
debug ( 'unrefList find where we can insert' ) ;
var cur , them ;
for ( cur = unrefList . _ idlePrev ; cur != unrefList ; cur = cur . _ idlePrev ) {
them = cur . _ idleStart + cur . _ idleTimeout ;
if ( when < them ) {
debug ( 'unrefList inserting into middle of list' ) ;
L . append ( cur , item ) ;
if ( unrefTimer . when > when ) {
debug ( 'unrefTimer is scheduled to fire too late, reschedule' ) ;
unrefTimer . start ( msecs , 0 ) ;
unrefTimer . when = when ;
}
return ;
}
}
debug ( 'unrefList append to end' ) ;
L . append ( unrefList , item ) ;
} ;