@@ -47,6 +47,7 @@ using v8::Object;
4747using v8::Promise;
4848using v8::PromiseHookType;
4949using v8::RetainedObjectInfo;
50+ using v8::String;
5051using v8::Symbol;
5152using v8::TryCatch;
5253using v8::Uint32Array;
@@ -216,23 +217,28 @@ bool DomainExit(Environment* env, v8::Local<v8::Object> object) {
216217
217218
218219static bool PreCallbackExecution(AsyncWrap* wrap, bool run_domain_cbs) {
219- AsyncHooks* async_hooks = wrap->env()->async_hooks();
220-
221220 if (wrap->env()->using_domains() && run_domain_cbs) {
222221 bool is_disposed = DomainEnter(wrap->env(), wrap->object());
223222 if (is_disposed)
224223 return false;
225224 }
226225
226+ return AsyncWrap::EmitBefore(wrap->env(), wrap->get_id());
227+ }
228+
229+
230+ bool AsyncWrap::EmitBefore(Environment* env, double async_id) {
231+ AsyncHooks* async_hooks = env->async_hooks();
232+
227233 if (async_hooks->fields()[AsyncHooks::kBefore] > 0) {
228- Local<Value> uid = Number::New(wrap-> env() ->isolate(), wrap->get_id() );
229- Local<Function> fn = wrap-> env() ->async_hooks_before_function();
230- TryCatch try_catch(wrap-> env() ->isolate());
234+ Local<Value> uid = Number::New(env->isolate(), async_id );
235+ Local<Function> fn = env->async_hooks_before_function();
236+ TryCatch try_catch(env->isolate());
231237 MaybeLocal<Value> ar = fn->Call(
232- wrap-> env() ->context(), Undefined(wrap-> env() ->isolate()), 1, &uid);
238+ env->context(), Undefined(env->isolate()), 1, &uid);
233239 if (ar.IsEmpty()) {
234- ClearFatalExceptionHandlers(wrap-> env() );
235- FatalException(wrap-> env() ->isolate(), try_catch);
240+ ClearFatalExceptionHandlers(env);
241+ FatalException(env->isolate(), try_catch);
236242 return false;
237243 }
238244 }
@@ -242,29 +248,36 @@ static bool PreCallbackExecution(AsyncWrap* wrap, bool run_domain_cbs) {
242248
243249
244250static bool PostCallbackExecution(AsyncWrap* wrap, bool run_domain_cbs) {
245- AsyncHooks* async_hooks = wrap->env()->async_hooks();
251+ if (!AsyncWrap::EmitAfter(wrap->env(), wrap->get_id()))
252+ return false;
253+
254+ if (wrap->env()->using_domains() && run_domain_cbs) {
255+ bool is_disposed = DomainExit(wrap->env(), wrap->object());
256+ if (is_disposed)
257+ return false;
258+ }
259+
260+ return true;
261+ }
262+
263+ bool AsyncWrap::EmitAfter(Environment* env, double async_id) {
264+ AsyncHooks* async_hooks = env->async_hooks();
246265
247266 // If the callback failed then the after() hooks will be called at the end
248267 // of _fatalException().
249268 if (async_hooks->fields()[AsyncHooks::kAfter] > 0) {
250- Local<Value> uid = Number::New(wrap-> env() ->isolate(), wrap->get_id() );
251- Local<Function> fn = wrap-> env() ->async_hooks_after_function();
252- TryCatch try_catch(wrap-> env() ->isolate());
269+ Local<Value> uid = Number::New(env->isolate(), async_id );
270+ Local<Function> fn = env->async_hooks_after_function();
271+ TryCatch try_catch(env->isolate());
253272 MaybeLocal<Value> ar = fn->Call(
254- wrap-> env() ->context(), Undefined(wrap-> env() ->isolate()), 1, &uid);
273+ env->context(), Undefined(env->isolate()), 1, &uid);
255274 if (ar.IsEmpty()) {
256- ClearFatalExceptionHandlers(wrap-> env() );
257- FatalException(wrap-> env() ->isolate(), try_catch);
275+ ClearFatalExceptionHandlers(env);
276+ FatalException(env->isolate(), try_catch);
258277 return false;
259278 }
260279 }
261280
262- if (wrap->env()->using_domains() && run_domain_cbs) {
263- bool is_disposed = DomainExit(wrap->env(), wrap->object());
264- if (is_disposed)
265- return false;
266- }
267-
268281 return true;
269282}
270283
@@ -526,32 +539,44 @@ AsyncWrap::~AsyncWrap() {
526539// and reused over their lifetime. This way a new uid can be assigned when
527540// the resource is pulled out of the pool and put back into use.
528541void AsyncWrap::AsyncReset() {
529- AsyncHooks* async_hooks = env()->async_hooks();
530542 async_id_ = env()->new_async_id();
531543 trigger_id_ = env()->get_init_trigger_id();
532544
545+ EmitAsyncInit(env(), object(),
546+ env()->async_hooks()->provider_string(provider_type()),
547+ async_id_, trigger_id_);
548+ }
549+
550+
551+ void AsyncWrap::EmitAsyncInit(Environment* env,
552+ Local<Object> object,
553+ Local<String> type,
554+ double async_id,
555+ double trigger_id) {
556+ AsyncHooks* async_hooks = env->async_hooks();
557+
533558 // Nothing to execute, so can continue normally.
534559 if (async_hooks->fields()[AsyncHooks::kInit] == 0) {
535560 return;
536561 }
537562
538- HandleScope scope(env() ->isolate());
539- Local<Function> init_fn = env() ->async_hooks_init_function();
563+ HandleScope scope(env->isolate());
564+ Local<Function> init_fn = env->async_hooks_init_function();
540565
541566 Local<Value> argv[] = {
542- Number::New(env() ->isolate(), get_id() ),
543- env()->async_hooks()->provider_string(provider_type()) ,
544- object() ,
545- Number::New(env() ->isolate(), get_trigger_id() ),
567+ Number::New(env->isolate(), async_id ),
568+ type ,
569+ object,
570+ Number::New(env->isolate(), trigger_id ),
546571 };
547572
548- TryCatch try_catch(env() ->isolate());
573+ TryCatch try_catch(env->isolate());
549574 MaybeLocal<Value> ret = init_fn->Call(
550- env() ->context(), object() , arraysize(argv), argv);
575+ env->context(), object, arraysize(argv), argv);
551576
552577 if (ret.IsEmpty()) {
553- ClearFatalExceptionHandlers(env() );
554- FatalException(env() ->isolate(), try_catch);
578+ ClearFatalExceptionHandlers(env);
579+ FatalException(env->isolate(), try_catch);
555580 }
556581}
557582
@@ -620,6 +645,38 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb,
620645 return rcheck.IsEmpty() ? Local<Value>() : ret_v;
621646}
622647
648+
649+ /* Public C++ embedder API */
650+
651+
652+ async_uid AsyncHooksGetCurrentId(Isolate* isolate) {
653+ return Environment::GetCurrent(isolate)->current_async_id();
654+ }
655+
656+
657+ async_uid AsyncHooksGetTriggerId(Isolate* isolate) {
658+ return Environment::GetCurrent(isolate)->get_init_trigger_id();
659+ }
660+
661+
662+ async_uid EmitAsyncInit(Isolate* isolate,
663+ Local<Object> resource,
664+ const char* name,
665+ async_uid trigger_id) {
666+ Environment* env = Environment::GetCurrent(isolate);
667+ async_uid async_id = env->new_async_id();
668+
669+ Local<String> type =
670+ String::NewFromUtf8(isolate, name, v8::NewStringType::kInternalized)
671+ .ToLocalChecked();
672+ AsyncWrap::EmitAsyncInit(env, resource, type, async_id, trigger_id);
673+ return async_id;
674+ }
675+
676+ void EmitAsyncDestroy(Isolate* isolate, async_uid id) {
677+ PushBackDestroyId(Environment::GetCurrent(isolate), id);
678+ }
679+
623680} // namespace node
624681
625682NODE_MODULE_CONTEXT_AWARE_BUILTIN(async_wrap, node::AsyncWrap::Initialize)
0 commit comments