From bb8e0ecc2e025913189825d110f5f2894d198519 Mon Sep 17 00:00:00 2001 From: "ChenYing Kuo (CY)" Date: Thu, 31 Oct 2024 21:49:31 +0800 Subject: [PATCH] Avoid touching Zenoh Session while exiting. (#37) * Avoid touching Zenoh Session while exiting. Signed-off-by: ChenYing Kuo * Register function right after opening Zenoh Session. Signed-off-by: ChenYing Kuo --------- Signed-off-by: ChenYing Kuo --- .../src/detail/rmw_context_impl_s.cpp | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/rmw_zenoh_cpp/src/detail/rmw_context_impl_s.cpp b/rmw_zenoh_cpp/src/detail/rmw_context_impl_s.cpp index 959f846a..8e549394 100644 --- a/rmw_zenoh_cpp/src/detail/rmw_context_impl_s.cpp +++ b/rmw_zenoh_cpp/src/detail/rmw_context_impl_s.cpp @@ -33,6 +33,16 @@ // TODO(clalancette): Make this configurable, or get it from the configuration #define SHM_BUFFER_SIZE_MB 10 +// 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 bool is_exiting = false; +void update_is_exiting() +{ + is_exiting = true; +} + ///============================================================================= void rmw_context_impl_s::graph_sub_data_handler(z_loaned_sample_t * sample, void * data) { @@ -171,7 +181,11 @@ rmw_ret_t rmw_context_impl_s::Data::shutdown() if (shm_provider_.has_value()) { z_drop(z_move(shm_provider_.value())); } - z_close(z_loan_mut(session_), NULL); + // Don't touch Zenoh Session if the ROS process is exiting, + // it will cause panic. + if (!is_exiting) { + z_close(z_loan_mut(session_), NULL); + } is_shutdown_ = true; return RMW_RET_OK; } @@ -214,6 +228,10 @@ rmw_context_impl_s::rmw_context_impl_s( RMW_SET_ERROR_MSG("Error setting up zenoh session"); throw std::runtime_error("Error setting up zenoh session."); } + // This atexit function is registered after ROS initialization, + // so it should be called before ROS finialization + // Check https://en.cppreference.com/w/cpp/utility/program/exit + atexit(update_is_exiting); auto close_session = rcpputils::make_scope_exit( [&session]() { z_close(z_loan_mut(session), NULL); @@ -335,8 +353,12 @@ rmw_context_impl_s::rmw_context_impl_s( ///============================================================================= rmw_context_impl_s::~rmw_context_impl_s() { - // std::lock_guard lock(data_->mutex_); - // z_drop(z_move(data_->session_)); + // Don't touch Zenoh Session if the ROS process is exiting, + // it will cause panic. + if (!is_exiting) { + std::lock_guard lock(data_->mutex_); + z_drop(z_move(data_->session_)); + } } ///=============================================================================