summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/node.cc42
-rw-r--r--src/node.js5
-rw-r--r--src/req_wrap.h21
3 files changed, 67 insertions, 1 deletions
diff --git a/src/node.cc b/src/node.cc
index c5e15161b4..7bfcdb8623 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -109,6 +109,11 @@ static Persistent<String> listeners_symbol;
static Persistent<String> uncaught_exception_symbol;
static Persistent<String> emit_symbol;
+static Persistent<String> domain_symbol;
+static Persistent<String> enter_symbol;
+static Persistent<String> exit_symbol;
+static Persistent<String> disposed_symbol;
+
static bool print_eval = false;
static bool force_repl = false;
@@ -1017,10 +1022,47 @@ MakeCallback(const Handle<Object> 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<Value> domain_v = object->Get(domain_symbol);
+ Local<Object> domain;
+ Local<Function> enter;
+ Local<Function> exit;
+ if (!domain_v->IsUndefined()) {
+ domain = domain_v->ToObject();
+ if (domain->Get(disposed_symbol)->BooleanValue()) {
+ // domain has been disposed of.
+ return Undefined();
+ }
+ enter = Local<Function>::Cast(domain->Get(enter_symbol));
+ enter->Call(domain, 0, NULL);
+ }
+
+ if (try_catch.HasCaught()) {
+ FatalException(try_catch);
+ return Undefined();
+ }
+
Local<Value> ret = callback->Call(object, argc, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
+ return Undefined();
+ }
+
+ if (!domain_v->IsUndefined()) {
+ exit = Local<Function>::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 05c0dd8ecd..cc5e7b65da 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 b8530e8950..c478ce0cdb 100644
--- a/src/req_wrap.h
+++ b/src/req_wrap.h
@@ -24,14 +24,35 @@
namespace node {
+static v8::Persistent<v8::String> process_symbol;
+static v8::Persistent<v8::String> domain_symbol;
+
template <typename T>
class ReqWrap {
public:
ReqWrap() {
v8::HandleScope scope;
object_ = v8::Persistent<v8::Object>::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<v8::Value> 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);