From bea9f0662c61b98a2dd4541a35266ce824279acb Mon Sep 17 00:00:00 2001 From: Taegyun Kim Date: Thu, 30 Oct 2025 18:21:16 -0400 Subject: [PATCH 1/3] use _exit --- core/utils.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core/utils.c b/core/utils.c index c944f6478..2821b78e1 100644 --- a/core/utils.c +++ b/core/utils.c @@ -3,6 +3,9 @@ extern struct uwsgi_server uwsgi; +// Forward declaration for function defined in uwsgi.c +extern void uwsgi_plugins_atexit(void); + #ifdef __BIG_ENDIAN__ uint16_t uwsgi_swap16(uint16_t x) { return (uint16_t) ((x & 0xff) << 8 | (x & 0xff00) >> 8); @@ -1930,7 +1933,7 @@ char *uwsgi_64bit2str(int64_t num) { char *uwsgi_size2str(size_t num) { char *str = uwsgi_malloc(sizeof(UMAX64_STR) + 1); snprintf(str, sizeof(UMAX64_STR) + 1, "%llu", (unsigned long long) num); - return str; + return str; } int uwsgi_num2str2(int num, char *ptr) { @@ -4476,8 +4479,14 @@ void uwsgi_opt_envdir(char *opt, char *value, void *foobar) { void uwsgi_exit(int status) { uwsgi.last_exit_code = status; - // disable macro expansion - (exit) (status); + + // Call uwsgi-specific cleanup (including Python plugin cleanup) + // This triggers Python atexit handlers before C++ destructors can interfere + uwsgi_plugins_atexit(); + + // Use _exit() to bypass C++ destructors that would cause race conditions + // At this point, Python cleanup has already completed safely + (_exit) (status); } int uwsgi_base128(struct uwsgi_buffer *ub, uint64_t l, int first) { From e96daa34e7306c5372b55ef63c84993e441f46f1 Mon Sep 17 00:00:00 2001 From: Taegyun Kim Date: Thu, 30 Oct 2025 20:57:12 -0400 Subject: [PATCH 2/3] check skip_atexit --- core/utils.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/utils.c b/core/utils.c index 2821b78e1..7ddb75d1b 100644 --- a/core/utils.c +++ b/core/utils.c @@ -4482,11 +4482,13 @@ void uwsgi_exit(int status) { // Call uwsgi-specific cleanup (including Python plugin cleanup) // This triggers Python atexit handlers before C++ destructors can interfere - uwsgi_plugins_atexit(); + if (!uwsgi.skip_atexit) { + uwsgi_plugins_atexit(); + } // Use _exit() to bypass C++ destructors that would cause race conditions // At this point, Python cleanup has already completed safely - (_exit) (status); + (_exit) (status); } int uwsgi_base128(struct uwsgi_buffer *ub, uint64_t l, int first) { From 118f04458b6f0fc9d9ae3294b2024e6d7151399d Mon Sep 17 00:00:00 2001 From: Taegyun Kim Date: Mon, 3 Nov 2025 15:19:52 -0500 Subject: [PATCH 3/3] update comments --- core/utils.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/utils.c b/core/utils.c index 7ddb75d1b..34b6d5f90 100644 --- a/core/utils.c +++ b/core/utils.c @@ -4480,14 +4480,11 @@ void uwsgi_opt_envdir(char *opt, char *value, void *foobar) { void uwsgi_exit(int status) { uwsgi.last_exit_code = status; - // Call uwsgi-specific cleanup (including Python plugin cleanup) - // This triggers Python atexit handlers before C++ destructors can interfere + // Call uwsgi-specific cleanup. if (!uwsgi.skip_atexit) { uwsgi_plugins_atexit(); } - // Use _exit() to bypass C++ destructors that would cause race conditions - // At this point, Python cleanup has already completed safely (_exit) (status); }