From 45e3a5e5dfc373aada7b2954f35047931b2c70c8 Mon Sep 17 00:00:00 2001 From: ChenYing Kuo Date: Mon, 16 Dec 2024 14:38:46 +0800 Subject: [PATCH] Don't close Zenoh session while the process is terminating. Signed-off-by: ChenYing Kuo --- rmw_zenoh_cpp/src/detail/zenoh_utils.cpp | 9 ++++++++- rmw_zenoh_cpp/src/detail/zenoh_utils.hpp | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rmw_zenoh_cpp/src/detail/zenoh_utils.cpp b/rmw_zenoh_cpp/src/detail/zenoh_utils.cpp index 35173656..421f68b5 100644 --- a/rmw_zenoh_cpp/src/detail/zenoh_utils.cpp +++ b/rmw_zenoh_cpp/src/detail/zenoh_utils.cpp @@ -26,6 +26,10 @@ namespace rmw_zenoh_cpp { +// Initialize the static variable in ZenohSession +std::once_flag ZenohSession::initFlag; +std::atomic ZenohSession::is_exiting(false); + /// Loan the zenoh session. ///============================================================================= const z_loaned_session_t * ZenohSession::loan() @@ -37,7 +41,10 @@ const z_loaned_session_t * ZenohSession::loan() ///============================================================================= ZenohSession::~ZenohSession() { - z_close(z_loan_mut(inner_), NULL); + // Don't close Zenoh session while the process is terminating + if (!is_exiting.load()) { + z_close(z_loan_mut(inner_), NULL); + } } ///============================================================================= diff --git a/rmw_zenoh_cpp/src/detail/zenoh_utils.hpp b/rmw_zenoh_cpp/src/detail/zenoh_utils.hpp index 1b1efc87..919e6948 100644 --- a/rmw_zenoh_cpp/src/detail/zenoh_utils.hpp +++ b/rmw_zenoh_cpp/src/detail/zenoh_utils.hpp @@ -18,8 +18,10 @@ #include #include +#include #include #include +#include #include #include "rmw/types.h" @@ -33,12 +35,27 @@ class ZenohSession final { public: ZenohSession(z_owned_session_t sess) - : inner_(sess) {} + : inner_(sess) { + std::call_once(initFlag, [] { + // This atexit function should be triggered before ZenohSession destruction + // Refer to https://en.cppreference.com/w/cpp/utility/program/exit + atexit([] { + ZenohSession::is_exiting.store(true); + }); + }); + } const z_loaned_session_t * loan(); ~ZenohSession(); private: z_owned_session_t inner_; + // Used to ensure atexit function is only registered once. + static std::once_flag initFlag; + // The variable is used to identify whether the process is trying to exit or not. + // The atexit function we registered will set the flag and prevent us from closing + // Zenoh Session. Zenoh API can't be used in atexit function, because Tokio context + // is already destroyed. It will cause panic if we do so. + static std::atomic is_exiting; }; ///=============================================================================