// 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;
// 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() {
do {
d = stack.pop();
} while (d && d !== this);
+ _domain_flag[0] = stack.length;
exports.active = stack[stack.length - 1];
process.domain = exports.active;
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;
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
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);
}
abort(); \
}
-// allow for quick domain check
-extern bool using_domains;
-
enum Endianness {
kLittleEndian, // _Not_ LITTLE_ENDIAN, clashes with endian.h.
kBigEndian
length);
}
+bool InDomain();
+
+v8::Handle<v8::Value> GetDomain();
+
} // namespace node
#endif // SRC_NODE_INTERNALS_H_
#define SRC_REQ_WRAP_H_
#include "node.h"
+#include "node_internals.h"
#include "queue.h"
namespace node {
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_);