Skip to content

Commit c35f484

Browse files
authored
Remove the need to Box rcl_node_t (#5)
Signed-off-by: Michael X. Grey <[email protected]>
1 parent 673d478 commit c35f484

File tree

8 files changed

+55
-30
lines changed

8 files changed

+55
-30
lines changed

rclrs/src/client.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl Drop for ClientHandle {
4343
// SAFETY: The entity lifecycle mutex is locked to protect against the risk of
4444
// global variables in the rmw implementation being unsafely modified during cleanup.
4545
unsafe {
46-
rcl_client_fini(rcl_client, &mut **rcl_node);
46+
rcl_client_fini(rcl_client, &mut *rcl_node);
4747
}
4848
}
4949
}
@@ -115,7 +115,7 @@ where
115115
unsafe {
116116
rcl_client_init(
117117
&mut rcl_client,
118-
&**rcl_node,
118+
&*rcl_node,
119119
type_support,
120120
topic_c_string.as_ptr(),
121121
&client_options,
@@ -263,7 +263,7 @@ where
263263
pub fn service_is_ready(&self) -> Result<bool, RclrsError> {
264264
let mut is_ready = false;
265265
let client = &mut *self.handle.rcl_client.lock().unwrap();
266-
let node = &mut **self.handle.node_handle.rcl_node.lock().unwrap();
266+
let node = &mut *self.handle.node_handle.rcl_node.lock().unwrap();
267267

268268
unsafe {
269269
// SAFETY both node and client are guaranteed to be valid here

rclrs/src/node.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
8181
pub(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

8697
impl 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
}

rclrs/src/node/builder.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
22
ffi::CString,
3-
sync::{Arc, Mutex},
3+
sync::{Arc, Mutex, atomic::AtomicBool},
44
};
55

66
use crate::{
@@ -276,8 +276,13 @@ impl NodeBuilder {
276276
let rcl_node_options = self.create_rcl_node_options()?;
277277
let rcl_context = &mut *self.context.rcl_context.lock().unwrap();
278278

279-
// SAFETY: Getting a zero-initialized value is always safe.
280-
let mut rcl_node = Box::new(unsafe { rcl_get_zero_initialized_node() });
279+
let handle = Arc::new(NodeHandle {
280+
// SAFETY: Getting a zero-initialized value is always safe.
281+
rcl_node: Mutex::new(unsafe { rcl_get_zero_initialized_node() }),
282+
context_handle: Arc::clone(&self.context),
283+
initialized: AtomicBool::new(false),
284+
});
285+
281286
unsafe {
282287
// SAFETY:
283288
// * The rcl_node is zero-initialized as mandated by this function.
@@ -287,7 +292,7 @@ impl NodeBuilder {
287292
// global variables in the rmw implementation being unsafely modified during cleanup.
288293
let _lifecycle_lock = ENTITY_LIFECYCLE_MUTEX.lock().unwrap();
289294
rcl_node_init(
290-
&mut *rcl_node,
295+
&mut *handle.rcl_node.lock().unwrap(),
291296
node_name.as_ptr(),
292297
node_namespace.as_ptr(),
293298
rcl_context,
@@ -296,10 +301,8 @@ impl NodeBuilder {
296301
.ok()?;
297302
};
298303

299-
let handle = Arc::new(NodeHandle {
300-
rcl_node: Mutex::new(rcl_node),
301-
context_handle: Arc::clone(&self.context),
302-
});
304+
handle.initialized.store(true, std::sync::atomic::Ordering::Release);
305+
303306
let parameter = {
304307
let rcl_node = handle.rcl_node.lock().unwrap();
305308
ParameterInterface::new(

rclrs/src/node/graph.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl Node {
139139
unsafe {
140140
let rcl_node = self.handle.rcl_node.lock().unwrap();
141141
rcl_get_topic_names_and_types(
142-
&**rcl_node,
142+
&*rcl_node,
143143
&mut rcutils_get_default_allocator(),
144144
false,
145145
&mut rcl_names_and_types,
@@ -169,7 +169,7 @@ impl Node {
169169
unsafe {
170170
let rcl_node = self.handle.rcl_node.lock().unwrap();
171171
rcl_get_node_names(
172-
&**rcl_node,
172+
&*rcl_node,
173173
rcutils_get_default_allocator(),
174174
&mut rcl_names,
175175
&mut rcl_namespaces,
@@ -217,7 +217,7 @@ impl Node {
217217
unsafe {
218218
let rcl_node = self.handle.rcl_node.lock().unwrap();
219219
rcl_get_node_names_with_enclaves(
220-
&**rcl_node,
220+
&*rcl_node,
221221
rcutils_get_default_allocator(),
222222
&mut rcl_names,
223223
&mut rcl_namespaces,
@@ -266,7 +266,7 @@ impl Node {
266266
// SAFETY: The topic_name string was correctly allocated previously
267267
unsafe {
268268
let rcl_node = self.handle.rcl_node.lock().unwrap();
269-
rcl_count_publishers(&**rcl_node, topic_name.as_ptr(), &mut count).ok()?
269+
rcl_count_publishers(&*rcl_node, topic_name.as_ptr(), &mut count).ok()?
270270
};
271271
Ok(count)
272272
}
@@ -282,7 +282,7 @@ impl Node {
282282
// SAFETY: The topic_name string was correctly allocated previously
283283
unsafe {
284284
let rcl_node = self.handle.rcl_node.lock().unwrap();
285-
rcl_count_subscribers(&**rcl_node, topic_name.as_ptr(), &mut count).ok()?
285+
rcl_count_subscribers(&*rcl_node, topic_name.as_ptr(), &mut count).ok()?
286286
};
287287
Ok(count)
288288
}
@@ -333,7 +333,7 @@ impl Node {
333333
unsafe {
334334
let rcl_node = self.handle.rcl_node.lock().unwrap();
335335
getter(
336-
&**rcl_node,
336+
&*rcl_node,
337337
&mut rcutils_get_default_allocator(),
338338
node_name.as_ptr(),
339339
node_namespace.as_ptr(),
@@ -369,7 +369,7 @@ impl Node {
369369
unsafe {
370370
let rcl_node = self.handle.rcl_node.lock().unwrap();
371371
getter(
372-
&**rcl_node,
372+
&*rcl_node,
373373
&mut rcutils_get_default_allocator(),
374374
topic.as_ptr(),
375375
false,

rclrs/src/parameter.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ pub use value::*;
1010

1111
use crate::vendor::rcl_interfaces::msg::rmw::{ParameterType, ParameterValue as RmwParameterValue};
1212

13-
use crate::{call_string_getter_with_rcl_node, rcl_bindings::*, Node, RclrsError};
13+
use crate::{
14+
call_string_getter_with_rcl_node, rcl_bindings::*, Node, RclrsError,
15+
ENTITY_LIFECYCLE_MUTEX,
16+
};
1417
use std::{
1518
collections::{btree_map::Entry, BTreeMap},
1619
fmt::Debug,
@@ -760,6 +763,7 @@ impl ParameterInterface {
760763
global_arguments: &rcl_arguments_t,
761764
) -> Result<Self, RclrsError> {
762765
let override_map = unsafe {
766+
let _lifecycle_lock = ENTITY_LIFECYCLE_MUTEX.lock().unwrap();
763767
let fqn = call_string_getter_with_rcl_node(rcl_node, rcl_node_get_fully_qualified_name);
764768
resolve_parameter_overrides(&fqn, node_arguments, global_arguments)?
765769
};

rclrs/src/publisher.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Drop for PublisherHandle {
3838
// SAFETY: The entity lifecycle mutex is locked to protect against the risk of
3939
// global variables in the rmw implementation being unsafely modified during cleanup.
4040
unsafe {
41-
rcl_publisher_fini(self.rcl_publisher.get_mut().unwrap(), &mut **rcl_node);
41+
rcl_publisher_fini(self.rcl_publisher.get_mut().unwrap(), &mut *rcl_node);
4242
}
4343
}
4444
}
@@ -111,7 +111,7 @@ where
111111
// variables in the rmw implementation being unsafely modified during cleanup.
112112
rcl_publisher_init(
113113
&mut rcl_publisher,
114-
&**rcl_node,
114+
&*rcl_node,
115115
type_support_ptr,
116116
topic_c_string.as_ptr(),
117117
&publisher_options,

rclrs/src/service.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Drop for ServiceHandle {
4141
// SAFETY: The entity lifecycle mutex is locked to protect against the risk of
4242
// global variables in the rmw implementation being unsafely modified during cleanup.
4343
unsafe {
44-
rcl_service_fini(rcl_service, &mut **rcl_node);
44+
rcl_service_fini(rcl_service, &mut *rcl_node);
4545
}
4646
}
4747
}
@@ -116,7 +116,7 @@ where
116116
// variables in the rmw implementation being unsafely modified during initialization.
117117
rcl_service_init(
118118
&mut rcl_service,
119-
&**rcl_node,
119+
&*rcl_node,
120120
type_support,
121121
topic_c_string.as_ptr(),
122122
&service_options as *const _,

rclrs/src/subscription.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl Drop for SubscriptionHandle {
4949
// SAFETY: The entity lifecycle mutex is locked to protect against the risk of
5050
// global variables in the rmw implementation being unsafely modified during cleanup.
5151
unsafe {
52-
rcl_subscription_fini(rcl_subscription, &mut **rcl_node);
52+
rcl_subscription_fini(rcl_subscription, &mut *rcl_node);
5353
}
5454
}
5555
}
@@ -129,7 +129,7 @@ where
129129
// variables in the rmw implementation being unsafely modified during cleanup.
130130
rcl_subscription_init(
131131
&mut rcl_subscription,
132-
&**rcl_node,
132+
&*rcl_node,
133133
type_support,
134134
topic_c_string.as_ptr(),
135135
&subscription_options,

0 commit comments

Comments
 (0)