mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
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<Array>. 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.
This commit is contained in:
parent
2ef1782bbc
commit
3f5d5847e2
@ -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;
|
||||
|
33
src/node.cc
33
src/node.cc
@ -132,6 +132,7 @@ Persistent<Object> process_p;
|
||||
static Persistent<Function> process_tickCallback;
|
||||
static Persistent<Object> binding_cache;
|
||||
static Persistent<Array> module_load_list;
|
||||
static Persistent<Array> p_domain_box;
|
||||
|
||||
static Cached<String> 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<Value>& args) {
|
||||
Local<Function> tdc = tdc_v.As<Function>();
|
||||
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<Array>());
|
||||
if (!args[1]->IsObject()) {
|
||||
fprintf(stderr, "_setupDomainUse second argument must be an object\n");
|
||||
abort();
|
||||
}
|
||||
Local<Object> flag = args[1].As<Object>();
|
||||
flag->SetIndexedPropertiesToExternalArrayData(&domain_flag,
|
||||
kExternalUnsignedIntArray,
|
||||
1);
|
||||
}
|
||||
|
||||
|
||||
bool InDomain() {
|
||||
return using_domains && domain_flag.count > 0;
|
||||
}
|
||||
|
||||
|
||||
Handle<Value> 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<v8::String> OneByteString(v8::Isolate* isolate,
|
||||
length);
|
||||
}
|
||||
|
||||
bool InDomain();
|
||||
|
||||
v8::Handle<v8::Value> GetDomain();
|
||||
|
||||
} // namespace node
|
||||
|
||||
#endif // SRC_NODE_INTERNALS_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<v8::Value> domain = v8::Context::GetCurrent()
|
||||
->Global()
|
||||
->Get(process_symbol)
|
||||
->ToObject()
|
||||
->Get(domain_symbol);
|
||||
|
||||
if (domain->IsObject()) {
|
||||
if (InDomain()) {
|
||||
v8::Local<v8::Value> domain = GetDomain();
|
||||
if (domain->IsObject())
|
||||
object->Set(domain_symbol, domain);
|
||||
}
|
||||
}
|
||||
|
||||
QUEUE_INSERT_TAIL(&req_wrap_queue, &req_wrap_queue_);
|
||||
|
Loading…
Reference in New Issue
Block a user