Skip to content

Commit 76ba1b5

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 01b98a7 commit 76ba1b5

File tree

11 files changed

+283
-91
lines changed

11 files changed

+283
-91
lines changed

src/async-wrap.cc

+82-17
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

+1
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

+1-1
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

+23-26
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ static void CheckImmediate(uv_check_t* handle) {
360360
env->immediate_callback_string(),
361361
0,
362362
nullptr,
363-
0, 0).ToLocalChecked();
363+
{0, 0}).ToLocalChecked();
364364
}
365365

366366

@@ -1295,8 +1295,7 @@ MaybeLocal<Value> MakeCallback(Environment* env,
12951295
const Local<Function> callback,
12961296
int argc,
12971297
Local<Value> argv[],
1298-
double async_id,
1299-
double trigger_id) {
1298+
async_context asyncContext) {
13001299
// If you hit this assertion, you forgot to enter the v8::Context first.
13011300
CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
13021301

@@ -1318,10 +1317,12 @@ MaybeLocal<Value> MakeCallback(Environment* env,
13181317
MaybeLocal<Value> ret;
13191318

13201319
{
1321-
AsyncHooks::ExecScope exec_scope(env, async_id, trigger_id);
1320+
AsyncHooks::ExecScope exec_scope(env, asyncContext.async_id,
1321+
asyncContext.trigger_async_id);
13221322

1323-
if (async_id != 0) {
1324-
if (!AsyncWrap::EmitBefore(env, async_id)) return Local<Value>();
1323+
if (asyncContext.async_id != 0) {
1324+
if (!AsyncWrap::EmitBefore(env, asyncContext.async_id))
1325+
return Local<Value>();
13251326
}
13261327

13271328
ret = callback->Call(env->context(), recv, argc, argv);
@@ -1333,8 +1334,9 @@ MaybeLocal<Value> MakeCallback(Environment* env,
13331334
ret : Undefined(env->isolate());
13341335
}
13351336

1336-
if (async_id != 0) {
1337-
if (!AsyncWrap::EmitAfter(env, async_id)) return Local<Value>();
1337+
if (asyncContext.async_id != 0) {
1338+
if (!AsyncWrap::EmitAfter(env, asyncContext.async_id))
1339+
return Local<Value>();
13381340
}
13391341
}
13401342

@@ -1355,8 +1357,8 @@ MaybeLocal<Value> MakeCallback(Environment* env,
13551357

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

13611363
Local<Object> process = env->process_object();
13621364

@@ -1381,13 +1383,11 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
13811383
const char* method,
13821384
int argc,
13831385
Local<Value> argv[],
1384-
async_uid async_id,
1385-
async_uid trigger_id) {
1386+
async_context asyncContext) {
13861387
Local<String> method_string =
13871388
String::NewFromUtf8(isolate, method, v8::NewStringType::kNormal)
13881389
.ToLocalChecked();
1389-
return MakeCallback(isolate, recv, method_string, argc, argv,
1390-
async_id, trigger_id);
1390+
return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext);
13911391
}
13921392

13931393

@@ -1396,14 +1396,12 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
13961396
Local<String> symbol,
13971397
int argc,
13981398
Local<Value> argv[],
1399-
async_uid async_id,
1400-
async_uid trigger_id) {
1399+
async_context asyncContext) {
14011400
Local<Value> callback_v = recv->Get(symbol);
14021401
if (callback_v.IsEmpty()) return Local<Value>();
14031402
if (!callback_v->IsFunction()) return Local<Value>();
14041403
Local<Function> callback = callback_v.As<Function>();
1405-
return MakeCallback(isolate, recv, callback, argc, argv,
1406-
async_id, trigger_id);
1404+
return MakeCallback(isolate, recv, callback, argc, argv, asyncContext);
14071405
}
14081406

14091407

@@ -1412,8 +1410,7 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
14121410
Local<Function> callback,
14131411
int argc,
14141412
Local<Value> argv[],
1415-
async_uid async_id,
1416-
async_uid trigger_id) {
1413+
async_context asyncContext) {
14171414
// Observe the following two subtleties:
14181415
//
14191416
// 1. The environment is retrieved from the callback function's context.
@@ -1424,7 +1421,7 @@ MaybeLocal<Value> MakeCallback(Isolate* isolate,
14241421
Environment* env = Environment::GetCurrent(callback->CreationContext());
14251422
Context::Scope context_scope(env->context());
14261423
return MakeCallback(env, recv.As<Value>(), callback, argc, argv,
1427-
async_id, trigger_id);
1424+
asyncContext);
14281425
}
14291426

14301427

@@ -1437,7 +1434,7 @@ Local<Value> MakeCallback(Isolate* isolate,
14371434
Local<Value>* argv) {
14381435
EscapableHandleScope handle_scope(isolate);
14391436
return handle_scope.Escape(
1440-
MakeCallback(isolate, recv, method, argc, argv, 0, 0)
1437+
MakeCallback(isolate, recv, method, argc, argv, {0, 0})
14411438
.FromMaybe(Local<Value>()));
14421439
}
14431440

@@ -1449,7 +1446,7 @@ Local<Value> MakeCallback(Isolate* isolate,
14491446
Local<Value>* argv) {
14501447
EscapableHandleScope handle_scope(isolate);
14511448
return handle_scope.Escape(
1452-
MakeCallback(isolate, recv, symbol, argc, argv, 0, 0)
1449+
MakeCallback(isolate, recv, symbol, argc, argv, {0, 0})
14531450
.FromMaybe(Local<Value>()));
14541451
}
14551452

@@ -1461,7 +1458,7 @@ Local<Value> MakeCallback(Isolate* isolate,
14611458
Local<Value>* argv) {
14621459
EscapableHandleScope handle_scope(isolate);
14631460
return handle_scope.Escape(
1464-
MakeCallback(isolate, recv, callback, argc, argv, 0, 0)
1461+
MakeCallback(isolate, recv, callback, argc, argv, {0, 0})
14651462
.FromMaybe(Local<Value>()));
14661463
}
14671464

@@ -4445,7 +4442,7 @@ void EmitBeforeExit(Environment* env) {
44454442
};
44464443
MakeCallback(env->isolate(),
44474444
process_object, "emit", arraysize(args), args,
4448-
0, 0).ToLocalChecked();
4445+
{0, 0}).ToLocalChecked();
44494446
}
44504447

44514448

@@ -4466,7 +4463,7 @@ int EmitExit(Environment* env) {
44664463

44674464
MakeCallback(env->isolate(),
44684465
process_object, "emit", arraysize(args), args,
4469-
0, 0).ToLocalChecked();
4466+
{0, 0}).ToLocalChecked();
44704467

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

0 commit comments

Comments
 (0)