joyent/node — pull request #3872 by shigeki (2012-08-16 02:43:36+00:00)
Title: move setImmediate from timer to uv_check

uv_check is the robust place to invoke setImmediate callbacks after process.nextTick and before timers(setTimeout/setInterval) for the following two reason.

#### 1. `immediateTimer.start(0, 1)` does not keep zero timeout value
The following test of setImmediate recursion shows its callbacks need time more than 1msec at every time. This is because of `uv_timer_again()` as commented in https://github.com/joyent/libuv/commit/90a75b0d8485d802a69056e7e63ae1ce749c69de#include-uv-h-P19 This would cause missing invocation of callbacks immediately after `uv_poll()`.

```javascript
function recur(n) {
var i = 0, max = n * 100, start = Date.now();
(function f() {
if ( i++ < max) {
setImmediate(f);
} else {
var etime = Date.now() - start;
console.log('iter=', max,', elapsed time=', etime , ', ave=', etime/max);
if (n < 10) recur(++n);
return;
}
})();
}
recur(1);
```
The resut is
```bash
> ./node ~/setImmedaite_recur_test.js
iter= 100 , elapsed time= 130 , ave= 1.3
iter= 200 , elapsed time= 263 , ave= 1.315
iter= 300 , elapsed time= 397 , ave= 1.3233333333333333
iter= 400 , elapsed time= 528 , ave= 1.32
iter= 500 , elapsed time= 650 , ave= 1.3
iter= 600 , elapsed time= 780 , ave= 1.3
iter= 700 , elapsed time= 900 , ave= 1.2857142857142858
iter= 800 , elapsed time= 1039 , ave= 1.29875
iter= 900 , elapsed time= 1179 , ave= 1.31
iter= 1000 , elapsed time= 1308 , ave= 1.308
```

#### 2. callback order changes when timeout value collides with another timers
It has a possibility for `setImmediate` to have the same timeou value as that of another timers. If this happens, the callback order is defined by the value of pointer of handles as
https://github.com/joyent/libuv/blob/master/src/unix/timer.c#L30-33
I think that `setImmediate callback` should be invoked after process.nextTick and before another timers. If not, the order has to be absolutely defined.

In both cases above, we can resolve them by fixing libuv, but I think that it is best to move the place of setImmediate to uv_check() where old process.nextTick was invoked.