static struct {
uint32_t length;
uint32_t index;
+ uint32_t in_tick;
+ uint32_t last_threw;
} tick_infobox;
#ifdef OPENSSL_NPN_NEGOTIATED
}
}
+ if (tick_infobox.last_threw == 1) {
+ tick_infobox.last_threw = 0;
+ return ret;
+ }
+
+ if (tick_infobox.in_tick == 1) {
+ return ret;
+ }
+
if (tick_infobox.length == 0) {
tick_infobox.index = 0;
return ret;
return Undefined(node_isolate);
}
+ if (tick_infobox.in_tick == 1) {
+ return ret;
+ }
+
if (tick_infobox.length == 0) {
tick_infobox.index = 0;
return ret;
Local<Object> info_box = Object::New();
info_box->SetIndexedPropertiesToExternalArrayData(&tick_infobox,
kExternalUnsignedIntArray,
- 2);
+ 4);
process->Set(String::NewSymbol("_tickInfoBox"), info_box);
// pre-set _events object for faster emit checks
};
startup.processNextTick = function() {
- var lastThrew = false;
var nextTickQueue = [];
- var needSpinner = true;
- var inTick = false;
- // this infobox thing is used so that the C++ code in src/node.cc
+ // this infoBox thing is used so that the C++ code in src/node.cc
// can have easy accesss to our nextTick state, and avoid unnecessary
// calls into process._tickCallback.
- // order is [length, index]
+ // order is [length, index, inTick, lastThrew]
// Never write code like this without very good reason!
var infoBox = process._tickInfoBox;
var length = 0;
var index = 1;
+ var inTick = 2;
+ var lastThrew = 3;
process.nextTick = nextTick;
// needs to be accessible from cc land
process._tickCallback = _tickCallback;
process._tickDomainCallback = _tickDomainCallback;
- function Tock(cb, domain) {
- this.callback = cb;
- this.domain = domain;
- }
-
function tickDone() {
if (infoBox[length] !== 0) {
if (infoBox[length] <= infoBox[index]) {
infoBox[length] = nextTickQueue.length;
}
}
- inTick = false;
+ infoBox[inTick] = 0;
infoBox[index] = 0;
}
function _tickCallback() {
var callback, nextTickLength, threw;
- if (inTick) return;
+ if (infoBox[inTick] === 1) return;
if (infoBox[length] === 0) {
infoBox[index] = 0;
return;
}
- inTick = true;
+ infoBox[inTick] = 1;
while (infoBox[index] < infoBox[length]) {
callback = nextTickQueue[infoBox[index]++].callback;
function _tickDomainCallback() {
var nextTickLength, tock, callback;
- if (lastThrew) {
- lastThrew = false;
+ if (infoBox[lastThrew] === 1) {
+ infoBox[lastThrew] = 0;
return;
}
- if (inTick) return;
+ if (infoBox[inTick] === 1) return;
if (infoBox[length] === 0) {
infoBox[index] = 0;
return;
}
- inTick = true;
+ infoBox[inTick] = 1;
while (infoBox[index] < infoBox[length]) {
tock = nextTickQueue[infoBox[index]++];
if (tock.domain._disposed) continue;
tock.domain.enter();
}
- lastThrew = true;
+ infoBox[lastThrew] = 1;
try {
callback();
- lastThrew = false;
+ infoBox[lastThrew] = 0;
} finally {
- if (lastThrew) tickDone();
+ if (infoBox[lastThrew] === 1) tickDone();
}
if (tock.domain)
tock.domain.exit();
if (process._exiting)
return;
- nextTickQueue.push(new Tock(callback, null));
+ nextTickQueue.push({ callback: callback, domain: null });
infoBox[length]++;
}
if (process._exiting)
return;
- nextTickQueue.push(new Tock(callback, process.domain));
+ nextTickQueue.push({ callback: callback, domain: process.domain });
infoBox[length]++;
}
};