@ -94,8 +94,8 @@ const TIMEOUT_MAX = 2147483647; // 2^31-1
//
// - key = time in milliseconds
// - value = linked list
const refedLists = { } ;
const unrefedLists = { } ;
const refedLists = Object . create ( null ) ;
const unrefedLists = Object . create ( null ) ;
// Schedule or re-schedule a timer.
@ -128,23 +128,28 @@ function insert(item, unrefed) {
var list = lists [ msecs ] ;
if ( ! list ) {
debug ( 'no %d list was found in insert, creating a new one' , msecs ) ;
// Make a new linked list of timers, and create a TimerWrap to schedule
// processing for the list.
list = new TimersList ( msecs , unrefed ) ;
L . init ( list ) ;
list . _ timer . _ list = list ;
if ( unrefed === true ) list . _ timer . unref ( ) ;
list . _ timer . start ( msecs ) ;
lists [ msecs ] = list ;
list . _ timer [ kOnTimeout ] = listOnTimeout ;
lists [ msecs ] = list = createTimersList ( msecs , unrefed ) ;
}
L . append ( list , item ) ;
assert ( ! L . isEmpty ( list ) ) ; // list is not empty
}
function createTimersList ( msecs , unrefed ) {
// Make a new linked list of timers, and create a TimerWrap to schedule
// processing for the list.
const list = new TimersList ( msecs , unrefed ) ;
L . init ( list ) ;
list . _ timer . _ list = list ;
if ( unrefed === true ) list . _ timer . unref ( ) ;
list . _ timer . start ( msecs ) ;
list . _ timer [ kOnTimeout ] = listOnTimeout ;
return list ;
}
function TimersList ( msecs , unrefed ) {
this . _ idleNext = null ; // Create the list with the linkedlist properties to
this . _ idlePrev = null ; // prevent any unnecessary hidden class changes.
@ -229,7 +234,7 @@ function tryOnTimeout(timer, list) {
timer . _ called = true ;
var threw = true ;
try {
timer . _ onTimeout ( ) ;
ontimeout ( timer ) ;
threw = false ;
} finally {
if ( ! threw ) return ;
@ -317,51 +322,76 @@ exports.enroll = function(item, msecs) {
* /
exports . setTimeout = function ( callback , after ) {
exports . setTimeout = function ( callback , after , arg1 , arg2 , arg3 ) {
if ( typeof callback !== 'function' ) {
throw new TypeError ( '"callback" argument must be a function' ) ;
}
after *= 1 ; // coalesce to number or NaN
if ( ! ( after >= 1 && after <= TIMEOUT_MAX ) ) {
after = 1 ; // schedule on next tick, follows browser behaviour
var len = arguments . length ;
var args ;
if ( len === 3 ) {
args = [ arg1 ] ;
} else if ( len === 4 ) {
args = [ arg1 , arg2 ] ;
} else if ( len > 4 ) {
args = [ arg1 , arg2 , arg3 ] ;
for ( var i = 5 ; i < len ; i ++ )
// extend array dynamically, makes .apply run much faster in v6.0.0
args [ i - 2 ] = arguments [ i ] ;
}
var timer = new Timeout ( after ) ;
var length = arguments . length ;
var ontimeout = callback ;
switch ( length ) {
// fast cases
case 1 :
case 2 :
break ;
case 3 :
ontimeout = ( ) => callback . call ( timer , arguments [ 2 ] ) ;
break ;
case 4 :
ontimeout = ( ) => callback . call ( timer , arguments [ 2 ] , arguments [ 3 ] ) ;
break ;
case 5 :
ontimeout =
( ) => callback . call ( timer , arguments [ 2 ] , arguments [ 3 ] , arguments [ 4 ] ) ;
break ;
// slow case
default :
var args = new Array ( length - 2 ) ;
for ( var i = 2 ; i < length ; i ++ )
args [ i - 2 ] = arguments [ i ] ;
ontimeout = ( ) => callback . apply ( timer , args ) ;
break ;
}
timer . _ onTimeout = ontimeout ;
return createSingleTimeout ( callback , after , args ) ;
} ;
if ( process . domain ) timer . domain = process . domain ;
function createSingleTimeout ( callback , after , args ) {
after *= 1 ; // coalesce to number or NaN
if ( ! ( after >= 1 && after <= TIMEOUT_MAX ) )
after = 1 ; // schedule on next tick, follows browser behaviour
var timer = new Timeout ( after , callback , args ) ;
if ( process . domain )
timer . domain = process . domain ;
active ( timer ) ;
return timer ;
} ;
}
function ontimeout ( timer ) {
var args = timer . _ timerArgs ;
var callback = timer . _ onTimeout ;
if ( ! args )
callback . call ( timer ) ;
else {
switch ( args . length ) {
case 1 :
callback . call ( timer , args [ 0 ] ) ;
break ;
case 2 :
callback . call ( timer , args [ 0 ] , args [ 1 ] ) ;
break ;
case 3 :
callback . call ( timer , args [ 0 ] , args [ 1 ] , args [ 2 ] ) ;
break ;
default :
callback . apply ( timer , args ) ;
}
}
if ( timer . _ repeat )
rearm ( timer ) ;
}
function rearm ( timer ) {
// If timer is unref'd (or was - it's permanently removed from the list.)
if ( timer . _ handle && timer instanceof Timeout ) {
timer . _ handle . start ( timer . _ repeat ) ;
} else {
timer . _ idleTimeout = timer . _ repeat ;
active ( timer ) ;
}
}
const clearTimeout = exports . clearTimeout = function ( timer ) {
@ -376,66 +406,41 @@ const clearTimeout = exports.clearTimeout = function(timer) {
} ;
exports . setInterval = function ( callback , repeat ) {
exports . setInterval = function ( callback , repeat , arg1 , arg2 , arg3 ) {
if ( typeof callback !== 'function' ) {
throw new TypeError ( '"callback" argument must be a function' ) ;
}
repeat *= 1 ; // coalesce to number or NaN
var len = arguments . length ;
var args ;
if ( len === 3 ) {
args = [ arg1 ] ;
} else if ( len === 4 ) {
args = [ arg1 , arg2 ] ;
} else if ( len > 4 ) {
args = [ arg1 , arg2 , arg3 ] ;
for ( var i = 5 ; i < len ; i ++ )
// extend array dynamically, makes .apply run much faster in v6.0.0
args [ i - 2 ] = arguments [ i ] ;
}
return createRepeatTimeout ( callback , repeat , args ) ;
} ;
if ( ! ( repeat >= 1 && repeat <= TIMEOUT_MAX ) ) {
function createRepeatTimeout ( callback , repeat , args ) {
repeat *= 1 ; // coalesce to number or NaN
if ( ! ( repeat >= 1 && repeat <= TIMEOUT_MAX ) )
repeat = 1 ; // schedule on next tick, follows browser behaviour
}
var timer = new Timeout ( repeat ) ;
var length = arguments . length ;
var ontimeout = callback ;
switch ( length ) {
case 1 :
case 2 :
break ;
case 3 :
ontimeout = ( ) => callback . call ( timer , arguments [ 2 ] ) ;
break ;
case 4 :
ontimeout = ( ) => callback . call ( timer , arguments [ 2 ] , arguments [ 3 ] ) ;
break ;
case 5 :
ontimeout =
( ) => callback . call ( timer , arguments [ 2 ] , arguments [ 3 ] , arguments [ 4 ] ) ;
break ;
default :
var args = new Array ( length - 2 ) ;
for ( var i = 2 ; i < length ; i += 1 )
args [ i - 2 ] = arguments [ i ] ;
ontimeout = ( ) => callback . apply ( timer , args ) ;
break ;
}
timer . _ onTimeout = wrapper ;
timer . _ repeat = ontimeout ;
var timer = new Timeout ( repeat , callback , args ) ;
timer . _ repeat = repeat ;
if ( process . domain )
timer . domain = process . domain ;
if ( process . domain ) timer . domain = process . domain ;
active ( timer ) ;
return timer ;
function wrapper ( ) {
timer . _ repeat ( ) ;
// Timer might be closed - no point in restarting it
if ( ! timer . _ repeat )
return ;
// If timer is unref'd (or was - it's permanently removed from the list.)
if ( this . _ handle ) {
this . _ handle . start ( repeat ) ;
} else {
timer . _ idleTimeout = repeat ;
active ( timer ) ;
}
}
} ;
}
exports . clearInterval = function ( timer ) {
if ( timer && timer . _ repeat ) {
@ -445,19 +450,20 @@ exports.clearInterval = function(timer) {
} ;
function Timeout ( after ) {
function Timeout ( after , callback , args ) {
this . _ called = false ;
this . _ idleTimeout = after ;
this . _ idlePrev = this ;
this . _ idleNext = this ;
this . _ idleStart = null ;
this . _ onTimeout = null ;
this . _ onTimeout = callback ;
this . _ timerArgs = args ;
this . _ repeat = null ;
}
function unrefdHandle ( ) {
this . owner . _ onTimeout ( ) ;
ontimeout ( this . owner ) ;
if ( ! this . owner . _ repeat )
this . owner . close ( ) ;
}