Skip to content

Commit d3df842

Browse files
committed
Manage all rcl bindings with Handle structs
Signed-off-by: Michael X. Grey <[email protected]>
1 parent b7dd6a2 commit d3df842

File tree

14 files changed

+122
-105
lines changed

14 files changed

+122
-105
lines changed

rclrs/src/client.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,32 @@ use rosidl_runtime_rs::Message;
99

1010
use crate::error::{RclReturnCode, ToResult};
1111
use crate::MessageCow;
12-
use crate::{rcl_bindings::*, RclrsError};
12+
use crate::{rcl_bindings::*, RclrsError, NodeHandle};
1313

1414
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
1515
// they are running in. Therefore, this type can be safely sent to another thread.
1616
unsafe impl Send for rcl_client_t {}
1717

1818
/// Internal struct used by clients.
1919
pub struct ClientHandle {
20-
rcl_client_mtx: Mutex<rcl_client_t>,
21-
rcl_node_mtx: Arc<Mutex<rcl_node_t>>,
20+
rcl_client: Mutex<rcl_client_t>,
21+
node_handle: Arc<NodeHandle>,
2222
pub(crate) in_use_by_wait_set: Arc<AtomicBool>,
2323
}
2424

2525
impl ClientHandle {
2626
pub(crate) fn lock(&self) -> MutexGuard<rcl_client_t> {
27-
self.rcl_client_mtx.lock().unwrap()
27+
self.rcl_client.lock().unwrap()
2828
}
2929
}
3030

3131
impl Drop for ClientHandle {
3232
fn drop(&mut self) {
33-
let rcl_client = self.rcl_client_mtx.get_mut().unwrap();
34-
let rcl_node_mtx = &mut *self.rcl_node_mtx.lock().unwrap();
33+
let rcl_client = self.rcl_client.get_mut().unwrap();
34+
let rcl_node = &mut *self.node_handle.rcl_node.lock().unwrap();
3535
// SAFETY: No preconditions for this function
3636
unsafe {
37-
rcl_client_fini(rcl_client, rcl_node_mtx);
37+
rcl_client_fini(rcl_client, rcl_node);
3838
}
3939
}
4040
}
@@ -74,7 +74,7 @@ where
7474
T: rosidl_runtime_rs::Service,
7575
{
7676
/// Creates a new client.
77-
pub(crate) fn new(rcl_node_mtx: Arc<Mutex<rcl_node_t>>, topic: &str) -> Result<Self, RclrsError>
77+
pub(crate) fn new(node_handle: Arc<NodeHandle>, topic: &str) -> Result<Self, RclrsError>
7878
// This uses pub(crate) visibility to avoid instantiating this struct outside
7979
// [`Node::create_client`], see the struct's documentation for the rationale
8080
where
@@ -99,7 +99,7 @@ where
9999
// afterwards.
100100
rcl_client_init(
101101
&mut rcl_client,
102-
&*rcl_node_mtx.lock().unwrap(),
102+
&*node_handle.rcl_node.lock().unwrap(),
103103
type_support,
104104
topic_c_string.as_ptr(),
105105
&client_options,
@@ -108,8 +108,8 @@ where
108108
}
109109

110110
let handle = Arc::new(ClientHandle {
111-
rcl_client_mtx: Mutex::new(rcl_client),
112-
rcl_node_mtx,
111+
rcl_client: Mutex::new(rcl_client),
112+
node_handle,
113113
in_use_by_wait_set: Arc::new(AtomicBool::new(false)),
114114
});
115115

@@ -245,8 +245,8 @@ where
245245
///
246246
pub fn service_is_ready(&self) -> Result<bool, RclrsError> {
247247
let mut is_ready = false;
248-
let client = &mut *self.handle.rcl_client_mtx.lock().unwrap();
249-
let node = &mut *self.handle.rcl_node_mtx.lock().unwrap();
248+
let client = &mut *self.handle.rcl_client.lock().unwrap();
249+
let node = &mut *self.handle.node_handle.rcl_node.lock().unwrap();
250250

251251
unsafe {
252252
// SAFETY both node and client are guaranteed to be valid here

rclrs/src/context.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub struct Context {
4949
/// doing it to be consistent with the lifecycle management of other rcl
5050
/// bindings in this library.
5151
pub(crate) struct ContextHandle {
52-
handle: Mutex<rcl_context_t>,
52+
pub(crate) rcl_context: Mutex<rcl_context_t>,
5353
}
5454

5555
impl Context {
@@ -109,7 +109,9 @@ impl Context {
109109
ret?;
110110
}
111111
Ok(Self {
112-
rcl_context_mtx: Arc::new(Mutex::new(rcl_context)),
112+
handle: Arc::new(ContextHandle {
113+
rcl_context: Mutex::new(rcl_context),
114+
})
113115
})
114116
}
115117

@@ -120,7 +122,7 @@ impl Context {
120122
pub fn ok(&self) -> bool {
121123
// This will currently always return true, but once we have a signal handler, the signal
122124
// handler could call `rcl_shutdown()`, hence making the context invalid.
123-
let rcl_context = &mut *self.rcl_context_mtx.lock().unwrap();
125+
let rcl_context = &mut *self.handle.rcl_context.lock().unwrap();
124126
// SAFETY: No preconditions for this function.
125127
unsafe { rcl_context_is_valid(rcl_context) }
126128
}

rclrs/src/executor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl SingleThreadedExecutor {
4242
for node in { self.nodes_mtx.lock().unwrap() }
4343
.iter()
4444
.filter_map(Weak::upgrade)
45-
.filter(|node| unsafe { rcl_context_is_valid(&*node.rcl_context_mtx.lock().unwrap()) })
45+
.filter(|node| unsafe { rcl_context_is_valid(&*node.handle.context_handle.rcl_context.lock().unwrap()) })
4646
{
4747
let wait_set = WaitSet::new_for_node(&node)?;
4848
let ready_entities = wait_set.wait(timeout)?;

rclrs/src/node.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,21 @@ pub struct Node {
7171
pub(crate) subscriptions_mtx: Mutex<Vec<Weak<dyn SubscriptionBase>>>,
7272
time_source: TimeSource,
7373
parameter: ParameterInterface,
74-
pub(crate) rcl_node: Arc<NodeHandle>,
74+
pub(crate) handle: Arc<NodeHandle>,
7575
}
7676

7777
/// This struct manages the lifetime of the rcl node, and accounts for its
7878
/// dependency on the lifetime of its context.
7979
pub(crate) struct NodeHandle {
80-
handle: Mutex<rcl_node_t>,
81-
rcl_context: Arc<ContextHandle>,
80+
pub(crate) rcl_node: Mutex<rcl_node_t>,
81+
pub(crate) context_handle: Arc<ContextHandle>,
8282
}
8383

8484
impl Eq for Node {}
8585

8686
impl PartialEq for Node {
8787
fn eq(&self, other: &Self) -> bool {
88-
Arc::ptr_eq(&self.rcl_node, &other.rcl_node)
88+
Arc::ptr_eq(&self.handle, &other.handle)
8989
}
9090
}
9191

@@ -185,7 +185,7 @@ impl Node {
185185
&self,
186186
getter: unsafe extern "C" fn(*const rcl_node_t) -> *const c_char,
187187
) -> String {
188-
unsafe { call_string_getter_with_handle(&self.rcl_node.handle.lock().unwrap(), getter) }
188+
unsafe { call_string_getter_with_handle(&self.handle.rcl_node.lock().unwrap(), getter) }
189189
}
190190

191191
/// Creates a [`Client`][1].
@@ -196,7 +196,7 @@ impl Node {
196196
where
197197
T: rosidl_runtime_rs::Service,
198198
{
199-
let client = Arc::new(Client::<T>::new(Arc::clone(&self.rcl_node_mtx), topic)?);
199+
let client = Arc::new(Client::<T>::new(Arc::clone(&self.handle), topic)?);
200200
{ self.clients_mtx.lock().unwrap() }.push(Arc::downgrade(&client) as Weak<dyn ClientBase>);
201201
Ok(client)
202202
}
@@ -212,7 +212,7 @@ impl Node {
212212
/// [2]: crate::spin_once
213213
pub fn create_guard_condition(&self) -> Arc<GuardCondition> {
214214
let guard_condition = Arc::new(GuardCondition::new_with_rcl_context(
215-
&mut self.rcl_context_mtx.lock().unwrap(),
215+
&mut self.handle.context_handle.rcl_context.lock().unwrap(),
216216
None,
217217
));
218218
{ self.guard_conditions_mtx.lock().unwrap() }
@@ -234,7 +234,7 @@ impl Node {
234234
F: Fn() + Send + Sync + 'static,
235235
{
236236
let guard_condition = Arc::new(GuardCondition::new_with_rcl_context(
237-
&mut self.rcl_context_mtx.lock().unwrap(),
237+
&mut self.handle.context_handle.rcl_context.lock().unwrap(),
238238
Some(Box::new(callback) as Box<dyn Fn() + Send + Sync>),
239239
));
240240
{ self.guard_conditions_mtx.lock().unwrap() }
@@ -255,7 +255,7 @@ impl Node {
255255
T: Message,
256256
{
257257
let publisher = Arc::new(Publisher::<T>::new(
258-
Arc::clone(&self.rcl_node_mtx),
258+
Arc::clone(&self.handle),
259259
topic,
260260
qos,
261261
)?);
@@ -276,7 +276,7 @@ impl Node {
276276
F: Fn(&rmw_request_id_t, T::Request) -> T::Response + 'static + Send,
277277
{
278278
let service = Arc::new(Service::<T>::new(
279-
Arc::clone(&self.rcl_node_mtx),
279+
Arc::clone(&self.handle),
280280
topic,
281281
callback,
282282
)?);
@@ -299,7 +299,7 @@ impl Node {
299299
T: Message,
300300
{
301301
let subscription = Arc::new(Subscription::<T>::new(
302-
Arc::clone(&self.rcl_node_mtx),
302+
Arc::clone(&self.handle),
303303
topic,
304304
qos,
305305
callback,
@@ -361,7 +361,7 @@ impl Node {
361361
// add description about this function is for getting actual domain_id
362362
// and about override of domain_id via node option
363363
pub fn domain_id(&self) -> usize {
364-
let rcl_node = &*self.rcl_node_mtx.lock().unwrap();
364+
let rcl_node = &*self.handle.rcl_node.lock().unwrap();
365365
let mut domain_id: usize = 0;
366366
let ret = unsafe {
367367
// SAFETY: No preconditions for this function.

rclrs/src/node/builder.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex};
33

44
use crate::rcl_bindings::*;
55
use crate::{
6-
ClockType, Context, Node, ParameterInterface, QoSProfile, RclrsError, TimeSource, ToResult,
6+
ClockType, Context, ContextHandle, Node, NodeHandle, ParameterInterface, QoSProfile, RclrsError, TimeSource, ToResult,
77
QOS_PROFILE_CLOCK,
88
};
99

@@ -42,7 +42,7 @@ use crate::{
4242
/// [1]: crate::Node
4343
/// [2]: crate::Node::builder
4444
pub struct NodeBuilder {
45-
context: Arc<Mutex<rcl_context_t>>,
45+
context: Arc<ContextHandle>,
4646
name: String,
4747
namespace: String,
4848
use_global_arguments: bool,
@@ -83,14 +83,14 @@ impl NodeBuilder {
8383
/// RclrsError::RclError { code: RclReturnCode::NodeInvalidName, .. }
8484
/// ));
8585
/// # Ok::<(), RclrsError>(())
86-
/// ```
87-
///
86+
/// ```
87+
///
8888
/// [1]: crate::Node#naming
8989
/// [2]: https://docs.ros2.org/latest/api/rmw/validate__node__name_8h.html#a5690a285aed9735f89ef11950b6e39e3
9090
/// [3]: NodeBuilder::build
9191
pub fn new(context: &Context, name: &str) -> NodeBuilder {
9292
NodeBuilder {
93-
context: context.rcl_context_mtx.clone(),
93+
context: Arc::clone(&context.handle),
9494
name: name.to_string(),
9595
namespace: "/".to_string(),
9696
use_global_arguments: true,
@@ -193,7 +193,7 @@ impl NodeBuilder {
193193
/// used in creating the context.
194194
///
195195
/// For more details about command line arguments, see [here][2].
196-
///
196+
///
197197
/// # Example
198198
/// ```
199199
/// # use rclrs::{Context, Node, NodeBuilder, RclrsError};
@@ -261,7 +261,7 @@ impl NodeBuilder {
261261
s: self.namespace.clone(),
262262
})?;
263263
let rcl_node_options = self.create_rcl_node_options()?;
264-
let rcl_context = &mut *self.context.lock().unwrap();
264+
let rcl_context = &mut *self.context.rcl_context.lock().unwrap();
265265

266266
// SAFETY: Getting a zero-initialized value is always safe.
267267
let mut rcl_node = unsafe { rcl_get_zero_initialized_node() };
@@ -280,15 +280,17 @@ impl NodeBuilder {
280280
.ok()?;
281281
};
282282

283-
let rcl_node_mtx = Arc::new(Mutex::new(rcl_node));
283+
let handle = Arc::new(NodeHandle {
284+
rcl_node: Mutex::new(rcl_node),
285+
context_handle: Arc::clone(&self.context),
286+
});
284287
let parameter = ParameterInterface::new(
285-
&rcl_node_mtx,
288+
&*handle.rcl_node.lock().unwrap(),
286289
&rcl_node_options.arguments,
287290
&rcl_context.global_arguments,
288291
)?;
289292
let node = Arc::new(Node {
290-
rcl_node_mtx,
291-
rcl_context_mtx: self.context.clone(),
293+
handle,
292294
clients_mtx: Mutex::new(vec![]),
293295
guard_conditions_mtx: Mutex::new(vec![]),
294296
services_mtx: Mutex::new(vec![]),

rclrs/src/node/graph.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl Node {
138138
// SAFETY: rcl_names_and_types is zero-initialized as expected by this call
139139
unsafe {
140140
rcl_get_topic_names_and_types(
141-
&*self.rcl_node_mtx.lock().unwrap(),
141+
&*self.handle.rcl_node.lock().unwrap(),
142142
&mut rcutils_get_default_allocator(),
143143
false,
144144
&mut rcl_names_and_types,
@@ -167,7 +167,7 @@ impl Node {
167167
// SAFETY: node_names and node_namespaces are zero-initialized as expected by this call.
168168
unsafe {
169169
rcl_get_node_names(
170-
&*self.rcl_node_mtx.lock().unwrap(),
170+
&*self.handle.rcl_node.lock().unwrap(),
171171
rcutils_get_default_allocator(),
172172
&mut rcl_names,
173173
&mut rcl_namespaces,
@@ -214,7 +214,7 @@ impl Node {
214214
// SAFETY: The node_names, namespaces, and enclaves are zero-initialized as expected by this call.
215215
unsafe {
216216
rcl_get_node_names_with_enclaves(
217-
&*self.rcl_node_mtx.lock().unwrap(),
217+
&*self.handle.rcl_node.lock().unwrap(),
218218
rcutils_get_default_allocator(),
219219
&mut rcl_names,
220220
&mut rcl_namespaces,
@@ -263,7 +263,7 @@ impl Node {
263263
// SAFETY: The topic_name string was correctly allocated previously
264264
unsafe {
265265
rcl_count_publishers(
266-
&*self.rcl_node_mtx.lock().unwrap(),
266+
&*self.handle.rcl_node.lock().unwrap(),
267267
topic_name.as_ptr(),
268268
&mut count,
269269
)
@@ -283,7 +283,7 @@ impl Node {
283283
// SAFETY: The topic_name string was correctly allocated previously
284284
unsafe {
285285
rcl_count_subscribers(
286-
&*self.rcl_node_mtx.lock().unwrap(),
286+
&*self.handle.rcl_node.lock().unwrap(),
287287
topic_name.as_ptr(),
288288
&mut count,
289289
)
@@ -337,7 +337,7 @@ impl Node {
337337
// SAFETY: node_name and node_namespace have been zero-initialized.
338338
unsafe {
339339
getter(
340-
&*self.rcl_node_mtx.lock().unwrap(),
340+
&*self.handle.rcl_node.lock().unwrap(),
341341
&mut rcutils_get_default_allocator(),
342342
node_name.as_ptr(),
343343
node_namespace.as_ptr(),
@@ -372,7 +372,7 @@ impl Node {
372372
// SAFETY: topic has been zero-initialized
373373
unsafe {
374374
getter(
375-
&*self.rcl_node_mtx.lock().unwrap(),
375+
&*self.handle.rcl_node.lock().unwrap(),
376376
&mut rcutils_get_default_allocator(),
377377
topic.as_ptr(),
378378
false,

rclrs/src/parameter.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -776,13 +776,12 @@ pub(crate) struct ParameterInterface {
776776

777777
impl ParameterInterface {
778778
pub(crate) fn new(
779-
rcl_node_mtx: &Arc<Mutex<rcl_node_t>>,
779+
rcl_node: &rcl_node_t,
780780
node_arguments: &rcl_arguments_t,
781781
global_arguments: &rcl_arguments_t,
782782
) -> Result<Self, RclrsError> {
783-
let rcl_node = rcl_node_mtx.lock().unwrap();
784783
let override_map = unsafe {
785-
let fqn = call_string_getter_with_handle(&rcl_node, rcl_node_get_fully_qualified_name);
784+
let fqn = call_string_getter_with_handle(rcl_node, rcl_node_get_fully_qualified_name);
786785
resolve_parameter_overrides(&fqn, node_arguments, global_arguments)?
787786
};
788787

rclrs/src/parameter/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ mod tests {
433433
let mut rcl_params = std::ptr::null_mut();
434434
unsafe {
435435
rcl_arguments_get_param_overrides(
436-
&ctx.rcl_context_mtx.lock().unwrap().global_arguments,
436+
&ctx.handle.rcl_context.lock().unwrap().global_arguments,
437437
&mut rcl_params,
438438
)
439439
.ok()?;

0 commit comments

Comments
 (0)