@@ -5,7 +5,7 @@ use std::{
55 ffi:: CStr ,
66 fmt,
77 os:: raw:: c_char,
8- sync:: { Arc , Mutex , Weak } ,
8+ sync:: { Arc , Mutex , Weak , atomic :: AtomicBool } ,
99 vec:: Vec ,
1010} ;
1111
@@ -79,19 +79,37 @@ pub struct Node {
7979///
8080/// [1]: <https://doc.rust-lang.org/reference/destructors.html>
8181pub ( crate ) struct NodeHandle {
82- pub ( crate ) rcl_node : Mutex < Box < rcl_node_t > > ,
82+ pub ( crate ) rcl_node : Mutex < rcl_node_t > ,
8383 pub ( crate ) context_handle : Arc < ContextHandle > ,
84+ /// In the humbe distro, rcl is sensitive to the address of the rcl_node_t
85+ /// object being moved (this issue seems to be gone in jazzy), so we need
86+ /// to initialize the rcl_node_t in-place inside this struct. In the event
87+ /// that the initialization fails (e.g. it was created with an invalid name)
88+ /// we need to make sure that we do not call rcl_node_fini on it while
89+ /// dropping the NodeHandle, so we keep track of successful initialization
90+ /// with this variable.
91+ ///
92+ /// We may be able to restructure this in the future when we no longer need
93+ /// to support Humble.
94+ pub ( crate ) initialized : AtomicBool ,
8495}
8596
8697impl Drop for NodeHandle {
8798 fn drop ( & mut self ) {
99+ if !self . initialized . load ( std:: sync:: atomic:: Ordering :: Acquire ) {
100+ // The node was not correctly initialized, e.g. it was created with
101+ // an invalid name, so we must not try to finalize it or else we
102+ // will get undefined behavior.
103+ return ;
104+ }
105+
88106 let _context_lock = self . context_handle . rcl_context . lock ( ) . unwrap ( ) ;
89107 let mut rcl_node = self . rcl_node . lock ( ) . unwrap ( ) ;
90108 let _lifecycle_lock = ENTITY_LIFECYCLE_MUTEX . lock ( ) . unwrap ( ) ;
91109
92110 // SAFETY: The entity lifecycle mutex is locked to protect against the risk of
93111 // global variables in the rmw implementation being unsafely modified during cleanup.
94- unsafe { rcl_node_fini ( & mut * * rcl_node) } ;
112+ unsafe { rcl_node_fini ( & mut * rcl_node) } ;
95113 }
96114}
97115
@@ -376,7 +394,7 @@ impl Node {
376394 let mut domain_id: usize = 0 ;
377395 let ret = unsafe {
378396 // SAFETY: No preconditions for this function.
379- rcl_node_get_domain_id ( & * * rcl_node, & mut domain_id)
397+ rcl_node_get_domain_id ( & * rcl_node, & mut domain_id)
380398 } ;
381399
382400 debug_assert_eq ! ( ret, 0 ) ;
@@ -451,7 +469,7 @@ impl Node {
451469 pub fn logger_name ( & self ) -> & str {
452470 let rcl_node = self . handle . rcl_node . lock ( ) . unwrap ( ) ;
453471 // SAFETY: No pre-conditions for this function
454- let name_raw_ptr = unsafe { rcl_node_get_logger_name ( & * * rcl_node) } ;
472+ let name_raw_ptr = unsafe { rcl_node_get_logger_name ( & * rcl_node) } ;
455473 if name_raw_ptr. is_null ( ) {
456474 return "" ;
457475 }
0 commit comments