diff options
author | ywave620 <60539365+ywave620@users.noreply.github.com> | 2023-02-28 11:17:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-28 03:17:46 +0000 |
commit | 7a37829ccb56b07f3091ca2840ac7b4519f0ca4a (patch) | |
tree | f91ca4c86057ea445283b4cc23298c153bb9589e /src | |
parent | bff7be8210ca445e53d7b7852726f711c264c386 (diff) | |
download | node-new-7a37829ccb56b07f3091ca2840ac7b4519f0ca4a.tar.gz |
src: fix cb scope bugs involved in termination
Be more aggresive to clean up the async id stack,
and ensure the cleanup when terminating.
Calling SetIdle() when terminating is not harmless.
When node terminates due to an unhandled exception,
v8 preseves the vm state, which is JS and notifies
node through PerIsolateMessageListener(). If node
calls SetIdle() later, v8 complains because it
requires the vm state to either be EXTERNEL or IDLE
when embedder calling SetIdle().
PR-URL: https://github.com/nodejs/node/pull/45596
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/api/callback.cc | 10 | ||||
-rw-r--r-- | src/api/environment.cc | 1 |
2 files changed, 8 insertions, 3 deletions
diff --git a/src/api/callback.cc b/src/api/callback.cc index 1287eb466f..3a8bd9155a 100644 --- a/src/api/callback.cc +++ b/src/api/callback.cc @@ -97,10 +97,9 @@ void InternalCallbackScope::Close() { if (closed_) return; closed_ = true; - Isolate* isolate = env_->isolate(); - auto idle = OnScopeLeave([&]() { isolate->SetIdle(true); }); + // This function must ends up with either cleanup the + // async id stack or pop the topmost one from it - if (!env_->can_call_into_js()) return; auto perform_stopping_check = [&]() { if (env_->is_stopping()) { MarkAsFailed(); @@ -109,6 +108,11 @@ void InternalCallbackScope::Close() { }; perform_stopping_check(); + if (env_->is_stopping()) return; + + Isolate* isolate = env_->isolate(); + auto idle = OnScopeLeave([&]() { isolate->SetIdle(true); }); + if (!failed_ && async_context_.async_id != 0 && !skip_hooks_) { AsyncWrap::EmitAfter(env_, async_context_.async_id); } diff --git a/src/api/environment.cc b/src/api/environment.cc index 3d3f864d4e..8aa1385f54 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -861,6 +861,7 @@ ThreadId AllocateEnvironmentThreadId() { } void DefaultProcessExitHandlerInternal(Environment* env, ExitCode exit_code) { + env->set_stopping(true); env->set_can_call_into_js(false); env->stop_sub_worker_contexts(); env->isolate()->DumpAndResetStats(); |