From: Trevor Norris Date: Wed, 7 Aug 2013 00:01:44 +0000 (-0700) Subject: domain: share object and state with native land X-Git-Tag: v0.11.6~70 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f5d5847e2f4f7e6d6f6557badda63b4cbf83e45;p=platform%2Fupstream%2Fnodejs.git domain: share object and state with native land Change process.domain to use a getter/setter and access that property via an array index. These are much faster to get from c++, and it can be passed to _setupDomainUse and stored as a Persistent. InDomain() and GetDomain() as trivial ways to access the domain information in the native layer. Important because we'll be able to quickly access if a domain is active. Instead of just whether the domain module has been loaded. --- diff --git a/lib/domain.js b/lib/domain.js index ac02f45..588fb75 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -32,8 +32,25 @@ var endMethods = ['end', 'abort', 'destroy', 'destroySoon']; // a few side effects. events.usingDomains = true; +// overwrite process.domain with a getter/setter that will allow for more +// effective optimizations +var _domain = [null]; +Object.defineProperty(process, 'domain', { + enumerable: true, + get: function() { + return _domain[0]; + }, + set: function(arg) { + return _domain[0] = arg; + } +}); + +// objects with external array data are excellent ways to communicate state +// between js and c++ w/o much overhead +var _domain_flag = {}; + // let the process know we're using domains -process._setupDomainUse(); +process._setupDomainUse(_domain, _domain_flag); exports.Domain = Domain; @@ -64,6 +81,7 @@ Domain.prototype.enter = function() { // to push it onto the stack so that we can pop it later. exports.active = process.domain = this; stack.push(this); + _domain_flag[0] = stack.length; }; Domain.prototype.exit = function() { @@ -74,6 +92,7 @@ Domain.prototype.exit = function() { do { d = stack.pop(); } while (d && d !== this); + _domain_flag[0] = stack.length; exports.active = stack[stack.length - 1]; process.domain = exports.active; diff --git a/src/node.cc b/src/node.cc index bb3ab87..7b1d843 100644 --- a/src/node.cc +++ b/src/node.cc @@ -132,6 +132,7 @@ Persistent process_p; static Persistent process_tickCallback; static Persistent binding_cache; static Persistent module_load_list; +static Persistent p_domain_box; static Cached exports_symbol; @@ -183,6 +184,11 @@ static struct { uint32_t last_threw; } tick_infobox; +// easily communicate domain depth +static struct { + uint32_t count; +} domain_flag; + #ifdef OPENSSL_NPN_NEGOTIATED static bool use_npn = true; #else @@ -917,6 +923,33 @@ void SetupDomainUse(const FunctionCallbackInfo& args) { Local tdc = tdc_v.As(); process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_tickCallback"), tdc); process_tickCallback.Reset(node_isolate, tdc); + if (!args[0]->IsArray()) { + fprintf(stderr, "_setupDomainUse first argument must be an array\n"); + abort(); + } + p_domain_box.Reset(node_isolate, args[0].As()); + if (!args[1]->IsObject()) { + fprintf(stderr, "_setupDomainUse second argument must be an object\n"); + abort(); + } + Local flag = args[1].As(); + flag->SetIndexedPropertiesToExternalArrayData(&domain_flag, + kExternalUnsignedIntArray, + 1); +} + + +bool InDomain() { + return using_domains && domain_flag.count > 0; +} + + +Handle GetDomain() { + // no domain can exist if no domain module has been loaded + if (!InDomain() || p_domain_box.IsEmpty()) + return Null(node_isolate); + + return PersistentToLocal(node_isolate, p_domain_box)->Get(0); } diff --git a/src/node_internals.h b/src/node_internals.h index 082368e..0c2bb0a 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -218,9 +218,6 @@ NO_RETURN void FatalError(const char* location, const char* message); abort(); \ } -// allow for quick domain check -extern bool using_domains; - enum Endianness { kLittleEndian, // _Not_ LITTLE_ENDIAN, clashes with endian.h. kBigEndian @@ -378,6 +375,10 @@ inline v8::Local OneByteString(v8::Isolate* isolate, length); } +bool InDomain(); + +v8::Handle GetDomain(); + } // namespace node #endif // SRC_NODE_INTERNALS_H_ diff --git a/src/req_wrap.h b/src/req_wrap.h index eb73f06..1187df9 100644 --- a/src/req_wrap.h +++ b/src/req_wrap.h @@ -23,6 +23,7 @@ #define SRC_REQ_WRAP_H_ #include "node.h" +#include "node_internals.h" #include "queue.h" namespace node { @@ -40,16 +41,10 @@ class ReqWrap { if (object.IsEmpty()) object = v8::Object::New(); persistent().Reset(node_isolate, object); - if (using_domains) { - v8::Local domain = v8::Context::GetCurrent() - ->Global() - ->Get(process_symbol) - ->ToObject() - ->Get(domain_symbol); - - if (domain->IsObject()) { + if (InDomain()) { + v8::Local domain = GetDomain(); + if (domain->IsObject()) object->Set(domain_symbol, domain); - } } QUEUE_INSERT_TAIL(&req_wrap_queue, &req_wrap_queue_);