diff options
author | isaacs <i@izs.me> | 2012-07-13 18:00:49 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-07-16 21:05:10 -0700 |
commit | 4e5fe2d45aef5aacf4a6c6c2db28f0b9cc64f123 (patch) | |
tree | fbb972592182ea52107b7f1a936297768fcf298d /src/node.js | |
parent | 0109a9f90acdfdb287436676f2384f7b072fbb6a (diff) | |
download | node-4e5fe2d45aef5aacf4a6c6c2db28f0b9cc64f123.tar.gz |
nextTick: Handle tick callbacks after each tick
Diffstat (limited to 'src/node.js')
-rw-r--r-- | src/node.js | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/node.js b/src/node.js index 029beb6c0..a86d72302 100644 --- a/src/node.js +++ b/src/node.js @@ -239,6 +239,8 @@ if (domain) domain.exit(); + // process the nextTicks after each time we get called. + process._tickCallback(); return ret; }; }; @@ -247,8 +249,19 @@ var nextTickQueue = []; var nextTickIndex = 0; var inTick = false; + var tickDepth = 0; + + // the maximum number of times it'll process something like + // nextTick(function f(){nextTick(f)}) + // It's unlikely, but not illegal, to hit this limit. When + // that happens, it yields to libuv's tick spinner. + // This is a loop counter, not a stack depth, so we aren't using + // up lots of memory here. I/O can sneak in before nextTick if this + // limit is hit, which is not ideal, but not terrible. + process.maxTickDepth = 1000; function tickDone() { + tickDepth = 0; nextTickQueue.splice(0, nextTickIndex); nextTickIndex = 0; inTick = false; @@ -259,28 +272,38 @@ process._tickCallback = function() { if (inTick) return; - var nextTickLength = nextTickQueue.length; - if (nextTickLength === 0) return; inTick = true; - while (nextTickIndex < nextTickLength) { - var tock = nextTickQueue[nextTickIndex++]; - var callback = tock.callback; - if (tock.domain) { - if (tock.domain._disposed) continue; - tock.domain.enter(); - } - var threw = true; - try { - callback(); - threw = false; - } finally { - if (threw) tickDone(); - } - if (tock.domain) { - tock.domain.exit(); + // always do this at least once. otherwise if process.maxTickDepth + // is set to some negative value, we'd never process any of them. + do { + tickDepth++; + var nextTickLength = nextTickQueue.length; + if (nextTickLength === 0) return tickDone(); + while (nextTickIndex < nextTickLength) { + var tock = nextTickQueue[nextTickIndex++]; + var callback = tock.callback; + if (tock.domain) { + if (tock.domain._disposed) continue; + tock.domain.enter(); + } + var threw = true; + try { + callback(); + threw = false; + } finally { + if (threw) tickDone(); + } + if (tock.domain) { + tock.domain.exit(); + } } - } + nextTickQueue.splice(0, nextTickIndex); + nextTickIndex = 0; + + // continue until the max depth or we run out of tocks. + } while (tickDepth < process.maxTickDepth && + nextTickQueue.length > 0); tickDone(); }; |