diff --git a/src/mono/mono/metadata/gc.c b/src/mono/mono/metadata/gc.c index f5f74cfd5073c..c6f37bbd1dc60 100644 --- a/src/mono/mono/metadata/gc.c +++ b/src/mono/mono/metadata/gc.c @@ -43,6 +43,7 @@ #include #include #include +#include #ifndef HOST_WIN32 #include #endif @@ -63,6 +64,8 @@ static gboolean gc_disabled; static gboolean finalizing_root_domain; +extern volatile gboolean term_signaled; + gboolean mono_log_finalizers; gboolean mono_do_not_finalize; static volatile gboolean suspend_finalizers; @@ -879,6 +882,17 @@ finalizer_thread (gpointer unused) mono_hazard_pointer_install_free_queue_size_callback (hazard_free_queue_is_too_big); while (!finished) { + + /* Just in case we've received a SIGTERM */ + if (term_signaled) { + int ec = mono_environment_exitcode_get(); + mono_runtime_try_shutdown(); + if (ec == 0) + exit(128+SIGTERM); + else + exit(ec); + } + /* Wait to be notified that there's at least one * finaliser to run */ diff --git a/src/mono/mono/mini/mini-posix.c b/src/mono/mono/mini/mini-posix.c index be8f83d396872..9565f4f6ef84c 100644 --- a/src/mono/mono/mini/mini-posix.c +++ b/src/mono/mono/mini/mini-posix.c @@ -97,6 +97,8 @@ #endif #include "mono/utils/mono-tls-inline.h" +gboolean term_signaled = FALSE; + #if defined(HOST_WATCHOS) void @@ -291,6 +293,15 @@ MONO_SIG_HANDLER_FUNC (static, sigquit_signal_handler) mono_chain_signal (MONO_SIG_HANDLER_PARAMS); } +MONO_SIG_HANDLER_FUNC (static, sigterm_signal_handler) +{ + term_signaled = TRUE; + + mono_gc_finalize_notify (); + + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); +} + MONO_SIG_HANDLER_FUNC (static, sigusr2_signal_handler) { gboolean enabled = mono_trace_is_enabled (); @@ -390,6 +401,8 @@ mono_runtime_posix_install_handlers (void) sigaddset (&signal_set, SIGFPE); add_signal_handler (SIGQUIT, sigquit_signal_handler, SA_RESTART); sigaddset (&signal_set, SIGQUIT); + add_signal_handler (SIGTERM, sigterm_signal_handler, SA_RESTART); + sigaddset (&signal_set, SIGTERM); add_signal_handler (SIGILL, mono_crashing_signal_handler, 0); sigaddset (&signal_set, SIGILL); add_signal_handler (SIGBUS, mono_sigsegv_signal_handler, 0);