};
-var immediateTimer = null;
-var immediateQueue = { started: false };
+var immediateQueue = {};
L.init(immediateQueue);
-function lazyImmediateInit() { // what's in a name?
- if (immediateTimer) return;
- immediateTimer = new Timer;
- immediateTimer.ontimeout = processImmediate;
-}
-
-
function processImmediate() {
- var immediate;
+ var immediate = L.shift(immediateQueue);
+
if (L.isEmpty(immediateQueue)) {
- immediateTimer.stop();
- immediateQueue.started = false;
- } else {
- immediate = L.shift(immediateQueue);
+ process._needImmediateCallback = false;
+ }
+ if (immediate._onImmediate) {
if (immediate.domain) immediate.domain.enter();
- immediate._onTimeout();
+ immediate._onImmediate();
if (immediate.domain) immediate.domain.exit();
}
L.init(immediate);
- immediate._onTimeout = callback;
+ immediate._onImmediate = callback;
if (arguments.length > 1) {
args = Array.prototype.slice.call(arguments, 1);
- immediate._onTimeout = function() {
+
+ immediate._onImmediate = function() {
callback.apply(null, args);
};
}
- if (!immediateQueue.started) {
- lazyImmediateInit();
- immediateTimer.start(0, 1);
- immediateQueue.started = true;
+ if (!process._needImmediateCallback) {
+ process._needImmediateCallback = true;
+ process._immediateCallback = processImmediate;
}
if (process.domain) immediate.domain = process.domain;
exports.clearImmediate = function(immediate) {
if (!immediate) return;
- immediate._onTimeout = undefined;
+ immediate._onImmediate = undefined;
L.remove(immediate);
if (L.isEmpty(immediateQueue)) {
- immediateTimer.stop();
- immediateQueue.started = false;
+ process._needImmediateCallback = false;
}
};
static bool need_tick_cb;
static Persistent<String> tick_callback_sym;
+static uv_check_t check_immediate_watcher;
+static uv_idle_t idle_immediate_dummy;
+static bool need_immediate_cb;
+static Persistent<String> immediate_callback_sym;
+
#ifdef OPENSSL_NPN_NEGOTIATED
static bool use_npn = true;
}
+static void CheckImmediate(uv_check_t* handle, int status) {
+ assert(handle == &check_immediate_watcher);
+ assert(status == 0);
+
+ HandleScope scope;
+
+ if (immediate_callback_sym.IsEmpty()) {
+ immediate_callback_sym = NODE_PSYMBOL("_immediateCallback");
+ }
+
+ MakeCallback(process, immediate_callback_sym, 0, NULL);
+}
+
+
+static void IdleImmediateDummy(uv_idle_t* handle, int status) {
+ // Do nothing. Only for maintaining event loop
+ assert(handle == &idle_immediate_dummy);
+ assert(status == 0);
+}
+
+
static inline const char *errno_string(int errorno) {
#define ERRNO_CASE(e) case e: return #e;
switch (errorno) {
static Handle<Value> DebugPause(const Arguments& args);
static Handle<Value> DebugEnd(const Arguments& args);
+
+Handle<Value> NeedImmediateCallbackGetter(Local<String> property,
+ const AccessorInfo& info) {
+ return Boolean::New(need_immediate_cb);
+}
+
+
+static void NeedImmediateCallbackSetter(Local<String> property,
+ Local<Value> value,
+ const AccessorInfo& info) {
+ HandleScope scope;
+
+ bool bool_value = value->BooleanValue();
+
+ if (need_immediate_cb == bool_value) return;
+
+ need_immediate_cb = bool_value;
+
+ if (need_immediate_cb) {
+ uv_check_start(&check_immediate_watcher, node::CheckImmediate);
+ // idle handle is needed only to maintain event loop
+ uv_idle_start(&idle_immediate_dummy, node::IdleImmediateDummy);
+ } else {
+ uv_check_stop(&check_immediate_watcher);
+ uv_idle_stop(&idle_immediate_dummy);
+ }
+}
+
+
Handle<Object> SetupProcessObject(int argc, char *argv[]) {
HandleScope scope;
process->Set(String::NewSymbol("pid"), Integer::New(getpid(), node_isolate));
process->Set(String::NewSymbol("features"), GetFeatures());
+ process->SetAccessor(String::New("_needImmediateCallback"),
+ NeedImmediateCallbackGetter,
+ NeedImmediateCallbackSetter);
// -e, --eval
if (eval_string) {
uv_idle_init(uv_default_loop(), &tick_spinner);
+ uv_check_init(uv_default_loop(), &check_immediate_watcher);
+ uv_unref((uv_handle_t*) &check_immediate_watcher);
+ uv_idle_init(uv_default_loop(), &idle_immediate_dummy);
+
V8::SetFatalErrorHandler(node::OnFatalError);
// Fetch a reference to the main isolate, so we have a reference to it