Skip to content
Browse files

process: allow ticker to cross communicate better

Using external memory values allows for quick communication between js
and cc land, so we can check if the js land callback needs to be run.
  • Loading branch information...
1 parent 2391024 commit 4f245e7e6a13c240ec99b3e9d822c155ef9cf068 @trevnorris trevnorris committed with Feb 13, 2013
Showing with 64 additions and 39 deletions.
  1. +26 −0 src/node.cc
  2. +38 −39 src/node.js
View
26 src/node.cc
@@ -139,6 +139,13 @@ static uv_idle_t tick_spinner;
static bool need_tick_cb;
static Persistent<String> tick_callback_sym;
+// for quick ref to tickCallback values
+struct TickInfoData {
+ uint32_t length;
+ uint32_t index;
+ uint32_t depth;
+};
+TickInfoData tick_infobox = { 0, 0, 0 };
#ifdef OPENSSL_NPN_NEGOTIATED
static bool use_npn = true;
@@ -939,6 +946,12 @@ MCWithDomain(const Handle<Object> object,
return Undefined(node_isolate);
}
+ if (tick_infobox.length == 0) {
+ tick_infobox.index = 0;
+ tick_infobox.depth = 0;
+ return Undefined(node_isolate);
+ }
+
// process nextTicks after call
process_tickWDCallback->Call(process, 0, NULL);
@@ -995,6 +1008,12 @@ MakeCallback(const Handle<Object> object,
return Undefined(node_isolate);
}
+ if (tick_infobox.length == 0) {
+ tick_infobox.index = 0;
+ tick_infobox.depth = 0;
+ return scope.Close(Undefined(node_isolate));
+ }
+
// process nextTicks after call
process_tickCallback->Call(process, 0, NULL);
@@ -2419,6 +2438,13 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
NODE_SET_METHOD(process, "binding", Binding);
+ // values use to cross communicate with processNextTick
+ Local<Object> info_box = Object::New();
+ info_box->SetIndexedPropertiesToExternalArrayData(&tick_infobox,
+ kExternalUnsignedIntArray,
+ 3);
+ process->Set(String::NewSymbol("_tickInfoBox"), info_box);
+
return process;
}
View
77 src/node.js
@@ -309,12 +309,11 @@
startup.processNextTick = function() {
var _needTickCallback = process._needTickCallback;
var nextTickQueue = [];
- var nextTickQueueLength = 0;
- var nextTickIndex = 0;
- var tickDepth = 0;
var usingDomains = false;
var needSpinner = true;
var inTick = false;
+ // order is [nextTickQueueLength, nextTickIndex, tickDepth]
+ var infoBox = process._tickInfoBox;
process._tickCallback = _tickCallback;
process._tickFromSpinner = _tickFromSpinner;
@@ -332,22 +331,22 @@
process.maxTickDepth = 1000;
function tickDone(tickDepth_) {
- if (nextTickQueueLength !== 0) {
- if (nextTickQueueLength <= nextTickIndex) {
+ if (infoBox[0] !== 0) {
+ if (infoBox[0] <= infoBox[1]) {
nextTickQueue = [];
- nextTickQueueLength = 0;
+ infoBox[0] = 0;
} else {
- nextTickQueue.splice(0, nextTickIndex);
- nextTickQueueLength = nextTickQueue.length;
+ nextTickQueue.splice(0, infoBox[1]);
+ infoBox[0] = nextTickQueue.length;
if (needSpinner) {
_needTickCallback();
needSpinner = false;
}
}
}
inTick = false;
- nextTickIndex = 0;
- tickDepth = tickDepth_;
+ infoBox[1] = 0;
+ infoBox[2] = tickDepth_;
}
function maxTickWarn() {
@@ -364,12 +363,12 @@
function _tickFromSpinner() {
needSpinner = true;
// coming from spinner, reset!
- if (tickDepth !== 0)
- tickDepth = 0;
+ if (infoBox[2] !== 0)
+ infoBox[2] = 0;
// no callbacks to run
- if (nextTickQueueLength === 0)
- return nextTickIndex = tickDepth = 0;
- if (nextTickQueue[nextTickQueueLength - 1].domain)
+ if (infoBox[0] === 0)
+ return infoBox[1] = infoBox[2] = 0;
+ if (nextTickQueue[infoBox[0] - 1].domain)
_tickWDCallback();
else
_tickCallback();
@@ -382,37 +381,37 @@
var callback, nextTickLength, threw;
if (inTick) return;
- if (nextTickQueueLength === 0) {
- nextTickIndex = 0;
- tickDepth = 0;
+ if (infoBox[0] === 0) {
+ infoBox[1] = 0;
+ infoBox[2] = 0;
return;
}
inTick = true;
- while (tickDepth++ < process.maxTickDepth) {
- nextTickLength = nextTickQueueLength;
- if (nextTickIndex === nextTickLength)
+ while (infoBox[2]++ < process.maxTickDepth) {
+ nextTickLength = infoBox[0];
+ if (infoBox[1] === nextTickLength)
return tickDone(0);
- while (nextTickIndex < nextTickLength) {
- callback = nextTickQueue[nextTickIndex++].callback;
+ while (infoBox[1] < nextTickLength) {
+ callback = nextTickQueue[infoBox[1]++].callback;
threw = true;
try {
callback();
threw = false;
} finally {
- if (threw) tickDone(tickDepth);
+ if (threw) tickDone(infoBox[2]);
}
}
}
- if (nextTickQueueLength > nextTickIndex)
+ if (infoBox[0] > infoBox[1])
return tickDone(0);
nextTickQueue = [];
- nextTickQueueLength = 0;
+ infoBox[0] = 0;
inTick = false;
- nextTickIndex = 0;
- tickDepth = 0;
+ infoBox[1] = 0;
+ infoBox[2] = 0;
}
function _tickWDCallback() {
@@ -424,23 +423,23 @@
// that error handler ALSO triggers multiple MakeCallbacks, then
// it'll try to keep clearing the queue, since the finally block
// fires *before* the error hits the top level and is handled.
- if (tickDepth >= process.maxTickDepth)
+ if (infoBox[2] >= process.maxTickDepth)
return _needTickCallback();
if (inTick) return;
inTick = true;
// always do this at least once. otherwise if process.maxTickDepth
// is set to some negative value, or if there were repeated errors
- // preventing tickDepth from being cleared, we'd never process any
+ // preventing infoBox[2] from being cleared, we'd never process any
// of them.
- while (tickDepth++ < process.maxTickDepth) {
- nextTickLength = nextTickQueueLength;
- if (nextTickIndex === nextTickLength)
+ while (infoBox[2]++ < process.maxTickDepth) {
+ nextTickLength = infoBox[0];
+ if (infoBox[1] === nextTickLength)
return tickDone(0);
- while (nextTickIndex < nextTickLength) {
- tock = nextTickQueue[nextTickIndex++];
+ while (infoBox[1] < nextTickLength) {
+ tock = nextTickQueue[infoBox[1]++];
callback = tock.callback;
if (tock.domain) {
if (tock.domain._disposed) continue;
@@ -452,8 +451,8 @@
threw = false;
} finally {
// finally blocks fire before the error hits the top level,
- // so we can't clear the tickDepth at this point.
- if (threw) tickDone(tickDepth);
+ // so we can't clear the infoBox[2] at this point.
+ if (threw) tickDone(infoBox[2]);
}
if (tock.domain) {
tock.domain.exit();
@@ -468,7 +467,7 @@
// on the way out, don't bother. it won't get fired anyway.
if (process._exiting)
return;
- if (tickDepth >= process.maxTickDepth)
+ if (infoBox[2] >= process.maxTickDepth)
maxTickWarn();
var obj = { callback: callback };
@@ -482,7 +481,7 @@
}
nextTickQueue.push(obj);
- nextTickQueueLength++;
+ infoBox[0]++;
}
};

0 comments on commit 4f245e7

Please sign in to comment.
Something went wrong with that request. Please try again.