@@ -36,39 +36,43 @@ std::string g_time_domain = "global"; // Assuming this is declared elsew
3636
3737void signalHandler (int sig) {
3838 std::cout << " Received signal: " << sig << std::endl;
39+ if (sig == SIGINT || sig == SIGTERM) {
40+ rclcpp::shutdown ();
41+ } else {
3942
40- std::string log_dir = " Log/" ;
43+ std::string log_dir = " Log/" ;
4144
42- // get current time
43- std::time_t now = std::time (nullptr );
44- std::tm *local_time = std::localtime (&now);
45+ // get current time
46+ std::time_t now = std::time (nullptr );
47+ std::tm *local_time = std::localtime (&now);
4548
46- // format date and time to string, format as "2024_05_20_12_34_56"
47- std::ostringstream time_stream;
48- time_stream << std::put_time (local_time, " %Y_%m_%d_%H_%M_%S" );
49+ // format date and time to string, format as "2024_05_20_12_34_56"
50+ std::ostringstream time_stream;
51+ time_stream << std::put_time (local_time, " %Y_%m_%d_%H_%M_%S" );
4952
50- // generate log file name
51- std::string log_file_name = g_camera_name + " _crash_stack_trace_" + time_stream.str () + " .log" ;
52- std::string log_file_path = log_dir + log_file_name;
53+ // generate log file name
54+ std::string log_file_name = g_camera_name + " _crash_stack_trace_" + time_stream.str () + " .log" ;
55+ std::string log_file_path = log_dir + log_file_name;
5356
54- if (!std::filesystem::exists (log_dir)) {
55- std::filesystem::create_directories (log_dir);
56- }
57+ if (!std::filesystem::exists (log_dir)) {
58+ std::filesystem::create_directories (log_dir);
59+ }
5760
58- std::cout << " Log crash stack trace to " << log_file_path << std::endl;
59- std::ofstream log_file (log_file_path, std::ios::app);
61+ std::cout << " Log crash stack trace to " << log_file_path << std::endl;
62+ std::ofstream log_file (log_file_path, std::ios::app);
6063
61- if (log_file.is_open ()) {
62- log_file << " Received signal: " << sig << std::endl;
64+ if (log_file.is_open ()) {
65+ log_file << " Received signal: " << sig << std::endl;
6366
64- backward::StackTrace st;
65- st.load_here (32 ); // Capture stack
66- backward::Printer p;
67- p.print (st, log_file); // Print stack to log file
68- }
67+ backward::StackTrace st;
68+ st.load_here (32 ); // Capture stack
69+ backward::Printer p;
70+ p.print (st, log_file); // Print stack to log file
71+ }
6972
70- log_file.close ();
71- exit (sig); // Exit program
73+ log_file.close ();
74+ exit (sig); // Exit program
75+ }
7276}
7377
7478namespace orbbec_camera {
@@ -97,10 +101,28 @@ OBCameraNodeDriver::OBCameraNodeDriver(const std::string &node_name, const std::
97101OBCameraNodeDriver::~OBCameraNodeDriver () {
98102 is_alive_.store (false );
99103
104+ // First stop the camera node cleanly before stopping threads
105+ if (ob_camera_node_) {
106+ try {
107+ ob_camera_node_->clean ();
108+ } catch (...) {
109+ RCLCPP_WARN_STREAM (logger_, " Exception during camera node cleanup in destructor" );
110+ }
111+ ob_camera_node_->stopGmslTrigger ();
112+ }
113+
114+ // Stop timers that might access the device
115+ if (sync_host_time_timer_) {
116+ sync_host_time_timer_->cancel ();
117+ sync_host_time_timer_.reset ();
118+ }
119+
100120 if (check_connect_timer_) {
121+ check_connect_timer_->cancel ();
101122 check_connect_timer_.reset ();
102123 }
103124
125+ // Now stop threads
104126 if (device_count_update_thread_ && device_count_update_thread_->joinable ()) {
105127 device_count_update_thread_->join ();
106128 }
@@ -111,9 +133,8 @@ OBCameraNodeDriver::~OBCameraNodeDriver() {
111133 reset_device_cond_.notify_all ();
112134 reset_device_thread_->join ();
113135 }
114- if (ob_camera_node_) {
115- ob_camera_node_->stopGmslTrigger ();
116- }
136+
137+ // Clean up shared memory
117138 if (orb_device_lock_shm_fd_ != -1 ) {
118139 close (orb_device_lock_shm_fd_);
119140 orb_device_lock_shm_fd_ = -1 ;
@@ -131,6 +152,8 @@ void OBCameraNodeDriver::init() {
131152 signal (SIGABRT, signalHandler); // abort
132153 signal (SIGFPE, signalHandler); // float point exception
133154 signal (SIGILL, signalHandler); // illegal instruction
155+ signal (SIGINT, signalHandler);
156+ signal (SIGTERM, signalHandler);
134157 ob::Context::setExtensionsDirectory (extension_path_.c_str ());
135158 if (config_path_.empty ()) {
136159 ctx_ = std::make_unique<ob::Context>();
@@ -301,6 +324,17 @@ void OBCameraNodeDriver::resetDevice() {
301324 RCLCPP_INFO_STREAM (logger_, " resetDevice : Reset device uid: " << device_unique_id_);
302325 std::lock_guard<decltype (device_lock_)> device_lock (device_lock_);
303326 {
327+ // First stop the camera node cleanly to prevent timer/diagnostic access to device
328+ if (ob_camera_node_) {
329+ try {
330+ // This will stop all timers and clean up properly
331+ ob_camera_node_->clean ();
332+ } catch (...) {
333+ RCLCPP_WARN_STREAM (logger_, " Exception during camera node cleanup during reset" );
334+ }
335+ }
336+
337+ // Now reset the objects
304338 ob_camera_node_.reset ();
305339 device_.reset ();
306340 device_info_.reset ();
@@ -817,6 +851,18 @@ void OBCameraNodeDriver::firmwareUpdateCallback(OBFwUpdateState state, const cha
817851 std::cout << " Message : " << message << std::endl << std::flush;
818852 if (state == STAT_DONE) {
819853 RCLCPP_INFO (logger_, " Reboot device" );
854+
855+ // Don't call clean() here to avoid deadlock - just stop timers and reboot
856+ // The resetDevice thread will handle proper cleanup when device disconnects
857+ if (sync_host_time_timer_) {
858+ try {
859+ sync_host_time_timer_->cancel ();
860+ sync_host_time_timer_.reset ();
861+ } catch (...) {
862+ // Ignore exceptions during timer cleanup
863+ }
864+ }
865+
820866 device_->reboot ();
821867 device_connected_ = false ;
822868 upgrade_firmware_ = " " ;
0 commit comments