diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index 8c9d7e1eafec73..556c6ba39e51f6 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -1,6 +1,9 @@ 'use strict'; const { getOptionValue } = require('internal/options'); +// Lazy load internal/trace_events_async_hooks only if the async_hooks +// trace event category is enabled. +let traceEventsAsyncHook; function prepareMainThreadExecution() { setupTraceCategoryState(); @@ -27,32 +30,27 @@ function prepareMainThreadExecution() { function setupTraceCategoryState() { const { - traceCategoryState, + asyncHooksEnabledInitial, setTraceCategoryStateUpdateHandler } = internalBinding('trace_events'); - const kCategoryAsyncHooks = 0; - let traceEventsAsyncHook; - - function toggleTraceCategoryState() { - // Dynamically enable/disable the traceEventsAsyncHook - const asyncHooksEnabled = !!traceCategoryState[kCategoryAsyncHooks]; - - if (asyncHooksEnabled) { - // Lazy load internal/trace_events_async_hooks only if the async_hooks - // trace event category is enabled. - if (!traceEventsAsyncHook) { - traceEventsAsyncHook = require('internal/trace_events_async_hooks'); - } - traceEventsAsyncHook.enable(); - } else if (traceEventsAsyncHook) { - traceEventsAsyncHook.disable(); - } - } - toggleTraceCategoryState(); + toggleTraceCategoryState(asyncHooksEnabledInitial); setTraceCategoryStateUpdateHandler(toggleTraceCategoryState); } +// Dynamically enable/disable the traceEventsAsyncHook +function toggleTraceCategoryState(asyncHooksEnabled) { + if (asyncHooksEnabled) { + if (!traceEventsAsyncHook) { + traceEventsAsyncHook = + require('internal/trace_events_async_hooks').createHook(); + } + traceEventsAsyncHook.enable(); + } else if (traceEventsAsyncHook) { + traceEventsAsyncHook.disable(); + } +} + // In general deprecations are intialized wherever the APIs are implemented, // this is used to deprecate APIs implemented in C++ where the deprecation // utitlities are not easily accessible. diff --git a/lib/internal/trace_events_async_hooks.js b/lib/internal/trace_events_async_hooks.js index b947cbb6152b4b..05bb7b85644915 100644 --- a/lib/internal/trace_events_async_hooks.js +++ b/lib/internal/trace_events_async_hooks.js @@ -83,4 +83,4 @@ function createHook() { }; } -module.exports = createHook(); +exports.createHook = createHook; diff --git a/src/env-inl.h b/src/env-inl.h index 1f66380cf4ca82..aca817605673fd 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -455,11 +455,6 @@ Environment::should_abort_on_uncaught_toggle() { return should_abort_on_uncaught_toggle_; } -inline AliasedBuffer& -Environment::trace_category_state() { - return trace_category_state_; -} - inline AliasedBuffer& Environment::stream_base_state() { return stream_base_state_; diff --git a/src/env.cc b/src/env.cc index 619d0ca19908cb..ead11b393a6911 100644 --- a/src/env.cc +++ b/src/env.cc @@ -21,6 +21,7 @@ namespace node { using errors::TryCatchScope; +using v8::Boolean; using v8::Context; using v8::EmbedderGraph; using v8::External; @@ -152,9 +153,8 @@ void Environment::TrackingTraceStateObserver::UpdateTraceCategoryState() { return; } - env_->trace_category_state()[0] = - *TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( - TRACING_CATEGORY_NODE1(async_hooks)); + bool async_hooks_enabled = (*(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( + TRACING_CATEGORY_NODE1(async_hooks)))) != 0; Isolate* isolate = env_->isolate(); HandleScope handle_scope(isolate); @@ -163,8 +163,9 @@ void Environment::TrackingTraceStateObserver::UpdateTraceCategoryState() { return; TryCatchScope try_catch(env_); try_catch.SetVerbose(true); - cb->Call(env_->context(), Undefined(isolate), - 0, nullptr).ToLocalChecked(); + Local args[] = {Boolean::New(isolate, async_hooks_enabled)}; + cb->Call(env_->context(), Undefined(isolate), arraysize(args), args) + .ToLocalChecked(); } static std::atomic next_thread_id{0}; @@ -183,7 +184,6 @@ Environment::Environment(IsolateData* isolate_data, tick_info_(context->GetIsolate()), timer_base_(uv_now(isolate_data->event_loop())), should_abort_on_uncaught_toggle_(isolate_, 1), - trace_category_state_(isolate_, kTraceCategoryCount), stream_base_state_(isolate_, StreamBase::kNumStreamBaseStateFields), flags_(flags), thread_id_(thread_id == kNoThreadId ? AllocateThreadId() : thread_id), diff --git a/src/env.h b/src/env.h index c4b3175d6a9ce1..41ec5805e6d574 100644 --- a/src/env.h +++ b/src/env.h @@ -705,7 +705,6 @@ class Environment { inline AliasedBuffer& should_abort_on_uncaught_toggle(); - inline AliasedBuffer& trace_category_state(); inline AliasedBuffer& stream_base_state(); // The necessary API for async_hooks. @@ -1026,8 +1025,6 @@ class Environment { AliasedBuffer should_abort_on_uncaught_toggle_; int should_not_abort_scope_counter_ = 0; - // Attached to a Uint8Array that tracks the state of trace category - AliasedBuffer trace_category_state_; std::unique_ptr trace_state_observer_; AliasedBuffer stream_base_state_; diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc index 6a0d4f037a76c4..5e30df41c4f4fa 100644 --- a/src/node_trace_events.cc +++ b/src/node_trace_events.cc @@ -1,6 +1,7 @@ #include "base_object-inl.h" #include "env.h" #include "node.h" +#include "node_internals.h" #include "node_v8_platform-inl.h" #include "tracing/agent.h" @@ -10,6 +11,7 @@ namespace node { using v8::Array; +using v8::Boolean; using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; @@ -148,9 +150,14 @@ void NodeCategorySet::Initialize(Local target, target->Set(context, trace, binding->Get(context, trace).ToLocalChecked()).FromJust(); - target->Set(context, - FIXED_ONE_BYTE_STRING(env->isolate(), "traceCategoryState"), - env->trace_category_state().GetJSArray()).FromJust(); + // Initial value of async hook trace events + bool async_hooks_enabled = (*(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( + TRACING_CATEGORY_NODE1(async_hooks)))) != 0; + target + ->Set(context, + FIXED_ONE_BYTE_STRING(env->isolate(), "asyncHooksEnabledInitial"), + Boolean::New(env->isolate(), async_hooks_enabled)) + .FromJust(); } } // namespace node