src: add ExecutionAsyncId getter for any Context

Adds a variant of AsyncHooksGetExecutionAsyncId that takes a V8 Context
and returns the async ID belonging to the Environment (if any) of that
Context. Sometimes we want to use Isolate::GetEnteredOrMicrotaskContext
insteads of Isolate::GetCurrentContext (e.g. recording the async ID in
a V8 GC prologue callback) when current context is not set.

PR-URL: https://github.com/nodejs/node/pull/57820
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
This commit is contained in:
Attila Szegedi 2025-04-17 20:00:05 +02:00 committed by GitHub
parent 9d6626a37e
commit ffb9bfb206
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 0 deletions

View File

@ -196,6 +196,12 @@ async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
return env->execution_async_id();
}
async_id AsyncHooksGetExecutionAsyncId(Local<Context> context) {
Environment* env = Environment::GetCurrent(context);
if (env == nullptr) return -1;
return env->execution_async_id();
}
async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
Environment* env = Environment::GetCurrent(isolate);
if (env == nullptr) return -1;

View File

@ -1404,6 +1404,12 @@ NODE_EXTERN void RequestInterrupt(Environment* env,
* I/O from native code. */
NODE_EXTERN async_id AsyncHooksGetExecutionAsyncId(v8::Isolate* isolate);
/* Returns the id of the current execution context. If the return value is
* zero then no execution has been set. This will happen if the user handles
* I/O from native code. */
NODE_EXTERN async_id
AsyncHooksGetExecutionAsyncId(v8::Local<v8::Context> context);
/* Return same value as async_hooks.triggerAsyncId(); */
NODE_EXTERN async_id AsyncHooksGetTriggerAsyncId(v8::Isolate* isolate);

View File

@ -12,6 +12,11 @@ void GetExecutionAsyncId(const FunctionCallbackInfo<Value>& args) {
node::AsyncHooksGetExecutionAsyncId(args.GetIsolate()));
}
void GetExecutionAsyncIdWithContext(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(node::AsyncHooksGetExecutionAsyncId(
args.GetIsolate()->GetCurrentContext()));
}
void GetTriggerAsyncId(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(
node::AsyncHooksGetTriggerAsyncId(args.GetIsolate()));
@ -19,6 +24,9 @@ void GetTriggerAsyncId(const FunctionCallbackInfo<Value>& args) {
void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "getExecutionAsyncId", GetExecutionAsyncId);
NODE_SET_METHOD(exports,
"getExecutionAsyncIdWithContext",
GetExecutionAsyncIdWithContext);
NODE_SET_METHOD(exports, "getTriggerAsyncId", GetTriggerAsyncId);
}

View File

@ -9,6 +9,10 @@ assert.strictEqual(
binding.getExecutionAsyncId(),
async_hooks.executionAsyncId(),
);
assert.strictEqual(
binding.getExecutionAsyncIdWithContext(),
async_hooks.executionAsyncId(),
);
assert.strictEqual(
binding.getTriggerAsyncId(),
async_hooks.triggerAsyncId(),
@ -19,6 +23,10 @@ process.nextTick(common.mustCall(() => {
binding.getExecutionAsyncId(),
async_hooks.executionAsyncId(),
);
assert.strictEqual(
binding.getExecutionAsyncIdWithContext(),
async_hooks.executionAsyncId(),
);
assert.strictEqual(
binding.getTriggerAsyncId(),
async_hooks.triggerAsyncId(),