From 5fe774104fc2ffa638d9ddfd0df1bdbc7cc84e47 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 4 Dec 2018 12:39:30 +0100 Subject: [PATCH] src: dispose of V8 platform in `process.exit()` Calling `process.exit()` calls the C `exit()` function, which in turn calls the destructors of static C++ objects. This can lead to race conditions with other concurrently executing threads; disposing of all Worker threads and then the V8 platform instance helps with this (although it might not be a full solution for all problems of this kind). Refs: https://github.com/nodejs/node/issues/24403 Refs: https://github.com/nodejs/node/issues/25007 PR-URL: https://github.com/nodejs/node/pull/25061 Reviewed-By: Gireesh Punathil Reviewed-By: Joyee Cheung Reviewed-By: Ben Noordhuis --- src/env.cc | 7 +++++-- src/node.cc | 4 ++++ src/node_internals.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/env.cc b/src/env.cc index 3bb4744469bb9c..4f6c6974c50f3f 100644 --- a/src/env.cc +++ b/src/env.cc @@ -862,10 +862,13 @@ void Environment::AsyncHooks::grow_async_ids_stack() { uv_key_t Environment::thread_local_env = {}; void Environment::Exit(int exit_code) { - if (is_main_thread()) + if (is_main_thread()) { + stop_sub_worker_contexts(); + DisposePlatform(); exit(exit_code); - else + } else { worker_context_->Exit(exit_code); + } } void Environment::stop_sub_worker_contexts() { diff --git a/src/node.cc b/src/node.cc index 52167a85909d7f..9975ff9d23f5b7 100644 --- a/src/node.cc +++ b/src/node.cc @@ -337,6 +337,10 @@ tracing::AgentWriterHandle* GetTracingAgentWriter() { return v8_platform.GetTracingAgentWriter(); } +void DisposePlatform() { + v8_platform.Dispose(); +} + #ifdef __POSIX__ static const unsigned kMaxSignal = 32; #endif diff --git a/src/node_internals.h b/src/node_internals.h index 03017fb4f5185e..0d07eb5d907b57 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -358,6 +358,7 @@ int ThreadPoolWork::CancelWork() { } tracing::AgentWriterHandle* GetTracingAgentWriter(); +void DisposePlatform(); static inline const char* errno_string(int errorno) { #define ERRNO_CASE(e) case e: return #e;