From 5af6a89a73955ffe22069ce75ccce938de75b658 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 27 Jul 2018 14:36:40 +0200 Subject: [PATCH] process: use owner_symbol for `_getActive*` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it easier to provide public APIs in the return types of `process._getActiveHandles()` and `process._getActiveRequests()`. PR-URL: https://github.com/nodejs/node/pull/22002 Backport-PR-URL: https://github.com/nodejs/node/pull/22507 Reviewed-By: Michaƫl Zasso --- src/async_wrap.cc | 21 +++++++++++++++++++++ src/async_wrap.h | 6 ++++++ src/node.cc | 12 +++--------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/async_wrap.cc b/src/async_wrap.cc index cb2a86f2924d64..7f2a0ece2f0055 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -736,6 +736,27 @@ std::string AsyncWrap::diagnostic_name() const { std::to_string(static_cast(async_id_)) + ")"; } +Local AsyncWrap::GetOwner() { + return GetOwner(env(), object()); +} + +Local AsyncWrap::GetOwner(Environment* env, Local obj) { + v8::EscapableHandleScope handle_scope(env->isolate()); + CHECK(!obj.IsEmpty()); + + v8::TryCatch ignore_exceptions(env->isolate()); + while (true) { + Local owner; + if (!obj->Get(env->context(), + env->owner_symbol()).ToLocal(&owner) || + !owner->IsObject()) { + return handle_scope.Escape(obj); + } + + obj = owner.As(); + } +} + } // 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 4a483aaea5127f..a84935eecb7626 100644 --- a/src/async_wrap.h +++ b/src/async_wrap.h @@ -179,6 +179,12 @@ class AsyncWrap : public BaseObject { static void WeakCallback(const v8::WeakCallbackInfo &info); + // Returns the object that 'owns' an async wrap. For example, for a + // TCP connection handle, this is the corresponding net.Socket. + v8::Local GetOwner(); + static v8::Local GetOwner(Environment* env, + v8::Local 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 ffec0c8ea8bbe6..847abaa6bbf5d6 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1143,7 +1143,7 @@ static void GetActiveRequests(const FunctionCallbackInfo& 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; @@ -1169,16 +1169,10 @@ void GetActiveHandles(const FunctionCallbackInfo& args) { Local argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; size_t idx = 0; - Local 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 = w->object(); - Local 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;