From 01f171925b43255bd6f5e1ce9483443def45be98 Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 13 Apr 2012 16:27:23 -0700 Subject: [PATCH] Domain hooks in ReqWrap and MakeCallback --- src/node.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ src/node.js | 5 ++++- src/req_wrap.h | 21 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/node.cc b/src/node.cc index c5e15161b40..7bfcdb8623c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -109,6 +109,11 @@ static Persistent listeners_symbol; static Persistent uncaught_exception_symbol; static Persistent emit_symbol; +static Persistent domain_symbol; +static Persistent enter_symbol; +static Persistent exit_symbol; +static Persistent disposed_symbol; + static bool print_eval = false; static bool force_repl = false; @@ -1017,10 +1022,47 @@ MakeCallback(const Handle object, TryCatch try_catch; + if (domain_symbol.IsEmpty()) { + domain_symbol = NODE_PSYMBOL("domain"); + enter_symbol = NODE_PSYMBOL("enter"); + exit_symbol = NODE_PSYMBOL("exit"); + disposed_symbol = NODE_PSYMBOL("_disposed"); + } + + Local domain_v = object->Get(domain_symbol); + Local domain; + Local enter; + Local exit; + if (!domain_v->IsUndefined()) { + domain = domain_v->ToObject(); + if (domain->Get(disposed_symbol)->BooleanValue()) { + // domain has been disposed of. + return Undefined(); + } + enter = Local::Cast(domain->Get(enter_symbol)); + enter->Call(domain, 0, NULL); + } + + if (try_catch.HasCaught()) { + FatalException(try_catch); + return Undefined(); + } + Local ret = callback->Call(object, argc, argv); if (try_catch.HasCaught()) { FatalException(try_catch); + return Undefined(); + } + + if (!domain_v->IsUndefined()) { + exit = Local::Cast(domain->Get(exit_symbol)); + exit->Call(domain, 0, NULL); + } + + if (try_catch.HasCaught()) { + FatalException(try_catch); + return Undefined(); } return scope.Close(ret); diff --git a/src/node.js b/src/node.js index 05c0dd8ecd3..cc5e7b65da6 100644 --- a/src/node.js +++ b/src/node.js @@ -238,7 +238,10 @@ for (var i = 0; i < l; i++) { var tock = q[i]; var callback = tock.callback; - if (tock.domain) tock.domain.enter(); + if (tock.domain) { + if (tock.domain._disposed) continue; + tock.domain.enter(); + } callback(); if (tock.domain) tock.domain.exit(); } diff --git a/src/req_wrap.h b/src/req_wrap.h index b8530e89505..c478ce0cdb7 100644 --- a/src/req_wrap.h +++ b/src/req_wrap.h @@ -24,14 +24,35 @@ namespace node { +static v8::Persistent process_symbol; +static v8::Persistent domain_symbol; + template class ReqWrap { public: ReqWrap() { v8::HandleScope scope; object_ = v8::Persistent::New(v8::Object::New()); + + // TODO: grab a handle to the current process.domain + if (process_symbol.IsEmpty()) { + process_symbol = NODE_PSYMBOL("process"); + domain_symbol = NODE_PSYMBOL("domain"); + } + + v8::Local domain = v8::Context::GetCurrent() + ->Global() + ->Get(process_symbol) + ->ToObject() + ->Get(domain_symbol); + + if (!domain->IsUndefined()) { + // fprintf(stderr, "setting domain on ReqWrap\n"); + object_->Set(domain_symbol, domain); + } } + ~ReqWrap() { // Assert that someone has called Dispatched() assert(req_.data == this);