Skip to content

Commit dd4789b

Browse files
addaleaxcodebytere
authored andcommitted
async_hooks: clear async_id_stack for terminations in more places
Termination exceptions are similar to uncaught exceptions in that they should clear the async id stack, because no ongoing async callbacks will be brought to completion when execution terminates. Previously, there was a check that made sure that that happened when the termination occurred during the callback itself, but no such check was in place for the case that the termination occurred during microtasks started by them. This commit adds such a check, both for microtasks and the `nextTick` queue. The latter addition doesn’t fix a crash, but still makes sense conceptually. The condition here is also flipped from applying only on Worker threads to also applying on the main thread, and setting the `failed_` flag rather than reading it. The former makes sense because the public C++ `Stop(env)` API can have the same effect as worker thread termination, but on the main thread rather than a Worker thread. PR-URL: #33347 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: David Carlier <[email protected]>
1 parent b1a7fda commit dd4789b

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/api/callback.cc

+10-3
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,13 @@ void InternalCallbackScope::Close() {
8484
closed_ = true;
8585

8686
if (!env_->can_call_into_js()) return;
87-
if (failed_ && !env_->is_main_thread() && env_->is_stopping()) {
88-
env_->async_hooks()->clear_async_id_stack();
89-
}
87+
auto perform_stopping_check = [&]() {
88+
if (env_->is_stopping()) {
89+
MarkAsFailed();
90+
env_->async_hooks()->clear_async_id_stack();
91+
}
92+
};
93+
perform_stopping_check();
9094

9195
if (!failed_ && async_context_.async_id != 0 && !skip_hooks_) {
9296
AsyncWrap::EmitAfter(env_, async_context_.async_id);
@@ -109,6 +113,8 @@ void InternalCallbackScope::Close() {
109113

110114
if (!tick_info->has_tick_scheduled()) {
111115
MicrotasksScope::PerformCheckpoint(env_->isolate());
116+
117+
perform_stopping_check();
112118
}
113119

114120
// Make sure the stack unwound properly. If there are nested MakeCallback's
@@ -136,6 +142,7 @@ void InternalCallbackScope::Close() {
136142
if (tick_callback->Call(env_->context(), process, 0, nullptr).IsEmpty()) {
137143
failed_ = true;
138144
}
145+
perform_stopping_check();
139146
}
140147

141148
MaybeLocal<Value> InternalMakeCallback(Environment* env,

0 commit comments

Comments
 (0)