Skip to content

Commit c7fb1ff

Browse files
AndreasMadsenaddaleax
authored andcommitted
async_hooks: C++ Embedder API overhaul
* Fix AsyncHooksGetTriggerAsyncId such it corresponds to async_hooks.triggerAsyncId and not async_hooks.initTriggerId. * Use an async_context struct instead of two async_uid values. This change was necessary since the fixing AsyncHooksGetTriggerAsyncId otherwise makes it impossible to get the correct default trigger id. It also prevents an invalid triggerAsyncId in MakeCallback. * Rename async_uid to async_id for consistency * Rename get_uid to get_async_id * Add get_trigger_async_id to AsyncResource class PR-URL: #14040 Backport-PR-URL: #14109 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Andreas Madsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent bfb2db6 commit c7fb1ff

File tree

11 files changed

+283
-91
lines changed

11 files changed

+283
-91
lines changed

src/async-wrap.cc

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,10 @@ void AsyncWrap::AsyncReset(bool silent) {
634634

635635
if (silent) return;
636636

637-
EmitAsyncInit(env(), object(),
638-
env()->async_hooks()->provider_string(provider_type()),
639-
async_id_, trigger_id_);
637+
AsyncWrap::EmitAsyncInit(
638+
env(), object(),
639+
env()->async_hooks()->provider_string(provider_type()),
640+
async_id_, trigger_id_);
640641
}
641642

642643

@@ -741,42 +742,106 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
741742
/* Public C++ embedder API */
742743

743744

744-
async_uid AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
745+
async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) {
745746
return Environment::GetCurrent(isolate)->current_async_id();
746747
}
747748

748-
async_uid AsyncHooksGetCurrentId(Isolate* isolate) {
749+
async_id AsyncHooksGetCurrentId(Isolate* isolate) {
749750
return AsyncHooksGetExecutionAsyncId(isolate);
750751
}
751752

752753

753-
async_uid AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
754-
return Environment::GetCurrent(isolate)->get_init_trigger_id();
754+
async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) {
755+
return Environment::GetCurrent(isolate)->trigger_id();
755756
}
756757

757-
async_uid AsyncHooksGetTriggerId(Isolate* isolate) {
758+
async_id AsyncHooksGetTriggerId(Isolate* isolate) {
758759
return AsyncHooksGetTriggerAsyncId(isolate);
759760
}
760761

761762

762-
async_uid EmitAsyncInit(Isolate* isolate,
763-
Local<Object> resource,
764-
const char* name,
765-
async_uid trigger_id) {
763+
async_context EmitAsyncInit(Isolate* isolate,
764+
Local<Object> resource,
765+
const char* name,
766+
async_id trigger_async_id) {
766767
Environment* env = Environment::GetCurrent(isolate);
767-
async_uid async_id = env->new_async_id();
768768

769+
// Initialize async context struct
770+
if (trigger_async_id == -1)
771+
trigger_async_id = env->get_init_trigger_id();
772+
773+
async_context context = {
774+
env->new_async_id(), // async_id_
775+
trigger_async_id // trigger_async_id_
776+
};
777+
778+
// Run init hooks
769779
Local<String> type =
770780
String::NewFromUtf8(isolate, name, v8::NewStringType::kInternalized)
771781
.ToLocalChecked();
772-
AsyncWrap::EmitAsyncInit(env, resource, type, async_id, trigger_id);
773-
return async_id;
782+
AsyncWrap::EmitAsyncInit(env, resource, type, context.async_id,
783+
context.trigger_async_id);
784+
785+
return context;
774786
}
775787

776-
void EmitAsyncDestroy(Isolate* isolate, async_uid id) {
777-
PushBackDestroyId(Environment::GetCurrent(isolate), id);
788+
void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) {
789+
PushBackDestroyId(Environment::GetCurrent(isolate), asyncContext.async_id);
778790
}
779791

780792
} // namespace node
781793

782794
NODE_MODULE_CONTEXT_AWARE_BUILTIN(async_wrap, node::AsyncWrap::Initialize)
795+
796+
797+
// Only legacy public API below this line.
798+
799+
namespace node {
800+
801+
MaybeLocal<Value> MakeCallback(Isolate* isolate,
802+
Local<Object> recv,
803+
Local<Function> callback,
804+
int argc,
805+
Local<Value>* argv,
806+
async_id asyncId,
807+
async_id triggerAsyncId) {
808+
return MakeCallback(isolate, recv, callback, argc, argv,
809+
{asyncId, triggerAsyncId});
810+
}
811+
812+
MaybeLocal<Value> MakeCallback(Isolate* isolate,
813+
Local<Object> recv,
814+
const char* method,
815+
int argc,
816+
Local<Value>* argv,
817+
async_id asyncId,
818+
async_id triggerAsyncId) {
819+
return MakeCallback(isolate, recv, method, argc, argv,
820+
{asyncId, triggerAsyncId});
821+
}
822+
823+
MaybeLocal<Value> MakeCallback(Isolate* isolate,
824+
Local<Object> recv,
825+
Local<String> symbol,
826+
int argc,
827+
Local<Value>* argv,
828+
async_id asyncId,
829+
async_id triggerAsyncId) {
830+
return MakeCallback(isolate, recv, symbol, argc, argv,
831+
{asyncId, triggerAsyncId});
832+
}
833+
834+
// Undo the Node-8.x-only alias from node.h
835+
#undef EmitAsyncInit
836+
837+
async_uid EmitAsyncInit(Isolate* isolate,
838+
Local<Object> resource,
839+
const char* name,
840+
async_id trigger_async_id) {
841+
return EmitAsyncInit__New(isolate,
842+
resource,
843+
name,
844+
trigger_async_id).async_id;
845+
}
846+
847+
} // namespace node

src/async-wrap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "base-object.h"
2828
#include "v8.h"
29+
#include "node.h"
2930

3031
#include <stdint.h>
3132

src/inspector_agent.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ bool Agent::StartIoThread(bool wait_for_connect) {
604604
message
605605
};
606606
MakeCallback(parent_env_->isolate(), process_object, emit_fn.As<Function>(),
607-
arraysize(argv), argv, 0, 0);
607+
arraysize(argv), argv, {0, 0});
608608

609609
return true;
610610
}

src/node.cc

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ static void CheckImmediate(uv_check_t* handle) {
363363
env->immediate_callback_string(),
364364
0,
365365
nullptr,
366-
0, 0).ToLocalChecked();
366+
{0, 0}).ToLocalChecked();
367367
}
368368

369369

@@ -1298,8 +1298,7 @@ MaybeLocal<Value> MakeCallback(Environment* env,
12981298
const Local<Function> callback,
12991299
int argc,
13001300
Local<Value> argv[],
1301-
double async_id,
1302-
double trigger_id) {
1301+
async_context asyncContext) {
13031302
// If you hit this assertion, you forgot to enter the v8::Context first.
13041303
CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
13051304

@@ -1321,10 +1320,12 @@ MaybeLocal<Value> MakeCallback(Environment* env,
13211320
MaybeLocal<Value> ret;
13221321

13231322
{
1324-
AsyncHooks::ExecScope exec_scope(env, async_id, trigger_id);
1323+
AsyncHooks::ExecScope exec_scope(env, asyncContext.async_id,
1324+
asyncContext.trigger_async_id);
13251325

1326-
if (async_id != 0) {
1327-
if (!AsyncWrap::EmitBefore(env, async_id)) return Local<Value>();
1326+
if (asyncContext.async_id != 0) {
1327+
if (!AsyncWrap::EmitBefore(env, asyncContext.async_id))
1328+
return Local<Value>();
13281329
}
13291330

13301331
ret = callback->Call(env->context(), recv, argc, argv);
@@ -1336,8 +1337,9 @@ MaybeLocal<Value> MakeCallback(Environment* env,
13361337
ret : Undefined(env->isolate());
13371338
}
13381339

1339-
if (async_id != 0) {
1340-
if (!AsyncWrap::EmitAfter(env, async_id)) return Local<Value>();
1340+
if (asyncContext.async_id != 0) {
1341+
if (!AsyncWrap::EmitAfter(env, asyncContext.async_id))
1342+
return Local<Value>();
13411343
}
13421344
}
13431345

@@ -1358,8 +1360,8 @@ MaybeLocal<Value> MakeCallback(Environment* env,
13581360

13591361
// Make sure the stack unwound properly. If there are nested MakeCallback's
13601362
// then it should return early and not reach this code.
1361-
CHECK_EQ(env->current_async_id(), async_id);
1362-
CHECK_EQ(env->trigger_id(), trigger_id);
1363+
CHECK_EQ(env->current_async_id(), asyncContext.async_id);
1364+
CHECK_EQ(env->trigger_id(), asyncContext.trigger_async_id);
13631365

13641366
Local<Object> process = env->process_object();
13651367

@@ -1384,13 +1386,11 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
13841386
const char* method,
13851387
int argc,
13861388
Local<Value> argv[],
1387-
async_uid async_id,
1388-
async_uid trigger_id) {
1389+
async_context asyncContext) {
13891390
Local<String> method_string =
13901391
String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal)
13911392
.ToLocalChecked();
1392-
return MakeCallback(isolate, recv, method_string, argc, argv,
1393-
async_id, trigger_id);
1393+
return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext);
13941394
}
13951395

13961396

@@ -1399,14 +1399,12 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
13991399
Local<String> symbol,
14001400
int argc,
14011401
Local<Value> argv[],
1402-
async_uid async_id,
1403-
async_uid trigger_id) {
1402+
async_context asyncContext) {
14041403
Local<Value> callback_v = recv->Get(symbol);
14051404
if (callback_v.IsEmpty()) return Local<Value>();
14061405
if (!callback_v->IsFunction()) return Local<Value>();
14071406
Local<Function> callback = callback_v.As<Function>();
1408-
return MakeCallback(isolate, recv, callback, argc, argv,
1409-
async_id, trigger_id);
1407+
return MakeCallback(isolate, recv, callback, argc, argv, asyncContext);
14101408
}
14111409

14121410

@@ -1415,8 +1413,7 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
14151413
Local<Function> callback,
14161414
int argc,
14171415
Local<Value> argv[],
1418-
async_uid async_id,
1419-
async_uid trigger_id) {
1416+
async_context asyncContext) {
14201417
// Observe the following two subtleties:
14211418
//
14221419
// 1. The environment is retrieved from the callback function's context.
@@ -1427,7 +1424,7 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
14271424
Environment* env = Environment::GetCurrent(callback->CreationContext());
14281425
Context::Scope context_scope(env->context());
14291426
return MakeCallback(env, recv.As<Value>(), callback, argc, argv,
1430-
async_id, trigger_id);
1427+
asyncContext);
14311428
}
14321429

14331430

@@ -1440,7 +1437,7 @@ Local<Value> MakeCallback(Isolate* isolate,
14401437
Local<Value>* argv) {
14411438
EscapableHandleScope handle_scope(isolate);
14421439
return handle_scope.Escape(
1443-
MakeCallback(isolate, recv, method, argc, argv, 0, 0)
1440+
MakeCallback(isolate, recv, method, argc, argv, {0, 0})
14441441
.FromMaybe(Local<Value>()));
14451442
}
14461443

@@ -1452,7 +1449,7 @@ Local<Value> MakeCallback(Isolate* isolate,
14521449
Local<Value>* argv) {
14531450
EscapableHandleScope handle_scope(isolate);
14541451
return handle_scope.Escape(
1455-
MakeCallback(isolate, recv, symbol, argc, argv, 0, 0)
1452+
MakeCallback(isolate, recv, symbol, argc, argv, {0, 0})
14561453
.FromMaybe(Local<Value>()));
14571454
}
14581455

@@ -1464,7 +1461,7 @@ Local<Value> MakeCallback(Isolate* isolate,
14641461
Local<Value>* argv) {
14651462
EscapableHandleScope handle_scope(isolate);
14661463
return handle_scope.Escape(
1467-
MakeCallback(isolate, recv, callback, argc, argv, 0, 0)
1464+
MakeCallback(isolate, recv, callback, argc, argv, {0, 0})
14681465
.FromMaybe(Local<Value>()));
14691466
}
14701467

@@ -4448,7 +4445,7 @@ void EmitBeforeExit(Environment* env) {
44484445
};
44494446
MakeCallback(env->isolate(),
44504447
process_object, "emit", arraysize(args), args,
4451-
0, 0).ToLocalChecked();
4448+
{0, 0}).ToLocalChecked();
44524449
}
44534450

44544451

@@ -4469,7 +4466,7 @@ int EmitExit(Environment* env) {
44694466

44704467
MakeCallback(env->isolate(),
44714468
process_object, "emit", arraysize(args), args,
4472-
0, 0).ToLocalChecked();
4469+
{0, 0}).ToLocalChecked();
44734470

44744471
// Reload exit code, it may be changed by `emit('exit')`
44754472
return process_object->Get(exitCode)->Int32Value();

0 commit comments

Comments
 (0)