summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/async_wrap.cc21
-rw-r--r--src/async_wrap.h6
-rw-r--r--src/node.cc12
3 files changed, 30 insertions, 9 deletions
diff --git a/src/async_wrap.cc b/src/async_wrap.cc
index 9d9d03b0fa..d47c0d6cfb 100644
--- a/src/async_wrap.cc
+++ b/src/async_wrap.cc
@@ -734,6 +734,27 @@ std::string AsyncWrap::diagnostic_name() const {
std::to_string(static_cast<int64_t>(async_id_)) + ")";
}
+Local<Object> AsyncWrap::GetOwner() {
+ return GetOwner(env(), object());
+}
+
+Local<Object> AsyncWrap::GetOwner(Environment* env, Local<Object> obj) {
+ v8::EscapableHandleScope handle_scope(env->isolate());
+ CHECK(!obj.IsEmpty());
+
+ v8::TryCatch ignore_exceptions(env->isolate());
+ while (true) {
+ Local<Value> owner;
+ if (!obj->Get(env->context(),
+ env->owner_symbol()).ToLocal(&owner) ||
+ !owner->IsObject()) {
+ return handle_scope.Escape(obj);
+ }
+
+ obj = owner.As<Object>();
+ }
+}
+
} // namespace node
NODE_BUILTIN_MODULE_CONTEXT_AWARE(async_wrap, node::AsyncWrap::Initialize)
diff --git a/src/async_wrap.h b/src/async_wrap.h
index 60078ee093..ee04479de0 100644
--- a/src/async_wrap.h
+++ b/src/async_wrap.h
@@ -178,6 +178,12 @@ class AsyncWrap : public BaseObject {
static void WeakCallback(const v8::WeakCallbackInfo<DestroyParam> &info);
+ // Returns the object that 'owns' an async wrap. For example, for a
+ // TCP connection handle, this is the corresponding net.Socket.
+ v8::Local<v8::Object> GetOwner();
+ static v8::Local<v8::Object> GetOwner(Environment* env,
+ v8::Local<v8::Object> obj);
+
// This is a simplified version of InternalCallbackScope that only runs
// the `before` and `after` hooks. Only use it when not actually calling
// back into JS; otherwise, use InternalCallbackScope.
diff --git a/src/node.cc b/src/node.cc
index 886243fd5c..a6bf512e04 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1138,7 +1138,7 @@ static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
for (auto w : *env->req_wrap_queue()) {
if (w->persistent().IsEmpty())
continue;
- argv[idx] = w->object();
+ argv[idx] = w->GetOwner();
if (++idx >= arraysize(argv)) {
fn->Call(ctx, ary, idx, argv).ToLocalChecked();
idx = 0;
@@ -1164,16 +1164,10 @@ void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
size_t idx = 0;
- Local<String> owner_sym = env->owner_string();
-
for (auto w : *env->handle_wrap_queue()) {
- if (w->persistent().IsEmpty() || !HandleWrap::HasRef(w))
+ if (!HandleWrap::HasRef(w))
continue;
- Local<Object> object = w->object();
- Local<Value> owner = object->Get(owner_sym);
- if (owner->IsUndefined())
- owner = object;
- argv[idx] = owner;
+ argv[idx] = w->GetOwner();
if (++idx >= arraysize(argv)) {
fn->Call(ctx, ary, idx, argv).ToLocalChecked();
idx = 0;