From 27acd9fcc7a4cc5ed2f12a6af600b0dfe6769c2c Mon Sep 17 00:00:00 2001 From: "Antonio S. Musumeci" Date: Sat, 18 Apr 2026 01:00:19 -0400 Subject: [PATCH] libfuse: use atomic fuse_session pointer in signal handler The signal handler reads the global session pointer from an async- signal context while another thread installs/removes the session via set/remove_signal_handlers. Use std::atomic with acquire/release ordering so the handler either sees NULL or a fully published session, never a torn pointer. --- vendored/libfuse/lib/fuse_signals.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/vendored/libfuse/lib/fuse_signals.cpp b/vendored/libfuse/lib/fuse_signals.cpp index ba9c70be..447d2701 100644 --- a/vendored/libfuse/lib/fuse_signals.cpp +++ b/vendored/libfuse/lib/fuse_signals.cpp @@ -8,19 +8,24 @@ #include "fuse_lowlevel.h" +#include + #include #include #include -static struct fuse_session *fuse_instance; +static std::atomic g_fuse_instance{nullptr}; static void exit_handler(int sig) { (void)sig; - if (fuse_instance) - fuse_session_exit(fuse_instance); + struct fuse_session *instance; + + instance = g_fuse_instance.load(std::memory_order_acquire); + if(instance) + fuse_session_exit(instance); } static int set_one_signal_handler(int sig, void (*handler)(int), int remove) @@ -54,20 +59,20 @@ int fuse_set_signal_handlers(struct fuse_session *se) (set_one_signal_handler(SIGPIPE, SIG_IGN, 0) == -1)) return -1; - fuse_instance = se; + g_fuse_instance.store(se,std::memory_order_release); + return 0; } void fuse_remove_signal_handlers(struct fuse_session *se) { - if (fuse_instance != se) - fprintf(stderr, - "fuse: fuse_remove_signal_handlers: unknown session\n"); - else - fuse_instance = NULL; - set_one_signal_handler(SIGINT, exit_handler, 1); set_one_signal_handler(SIGTERM, exit_handler, 1); set_one_signal_handler(SIGQUIT, exit_handler, 1); set_one_signal_handler(SIGPIPE, SIG_IGN, 1); + + if(g_fuse_instance.load(std::memory_order_acquire) != se) + fprintf(stderr,"mergerfs: fuse_remove_signal_handlers: unknown session\n"); + else + g_fuse_instance.store(nullptr,std::memory_order_release); }