Skip to content

Commit ac99b00

Browse files
authored
Test for Send and Sync implementations, and add missing implementations (#254)
1 parent 35be7c9 commit ac99b00

File tree

9 files changed

+111
-0
lines changed

9 files changed

+111
-0
lines changed

rclrs/src/context.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,15 @@ impl Context {
120120
mod tests {
121121
use super::*;
122122

123+
fn assert_send<T: Send>() {}
124+
fn assert_sync<T: Sync>() {}
125+
126+
#[test]
127+
fn context_is_send_and_sync() {
128+
assert_send::<Context>();
129+
assert_sync::<Context>();
130+
}
131+
123132
#[test]
124133
fn test_create_context() -> Result<(), RclrsError> {
125134
// If the context fails to be created, this will cause a panic

rclrs/src/node.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,17 @@ unsafe fn call_string_getter_with_handle(
328328
let cstr = CStr::from_ptr(char_ptr);
329329
cstr.to_string_lossy().into_owned()
330330
}
331+
332+
#[cfg(test)]
333+
mod tests {
334+
use super::*;
335+
336+
fn assert_send<T: Send>() {}
337+
fn assert_sync<T: Sync>() {}
338+
339+
#[test]
340+
fn node_is_send_and_sync() {
341+
assert_send::<Node>();
342+
assert_sync::<Node>();
343+
}
344+
}

rclrs/src/publisher.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ where
5555
}
5656
}
5757

58+
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
59+
// they are running in. Therefore, this type can be safely sent to another thread.
60+
unsafe impl<T> Send for Publisher<T> where T: Message {}
61+
// SAFETY: The type_support_ptr prevents the default Sync impl.
62+
// rosidl_message_type_support_t is a read-only type without interior mutability.
63+
unsafe impl<T> Sync for Publisher<T> where T: Message {}
64+
5865
impl<T> Publisher<T>
5966
where
6067
T: Message,

rclrs/src/publisher/loaned_message.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ where
6565
}
6666
}
6767

68+
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
69+
// they are running in. Therefore, this type can be safely sent to another thread.
70+
unsafe impl<'a, T> Send for LoanedMessage<'a, T> where T: RmwMessage {}
71+
// SAFETY: There is no interior mutability in this type. All mutation happens through &mut references.
72+
unsafe impl<'a, T> Sync for LoanedMessage<'a, T> where T: RmwMessage {}
73+
6874
impl<'a, T> LoanedMessage<'a, T>
6975
where
7076
T: RmwMessage,

rclrs/src/subscription/readonly_loaned_message.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,9 @@ where
4545
}
4646
}
4747
}
48+
49+
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
50+
// they are running in. Therefore, this type can be safely sent to another thread.
51+
unsafe impl<'a, T> Send for ReadOnlyLoanedMessage<'a, T> where T: RmwMessage {}
52+
// SAFETY: This type has no interior mutability, in fact it has no mutability at all.
53+
unsafe impl<'a, T> Sync for ReadOnlyLoanedMessage<'a, T> where T: RmwMessage {}

rclrs/src/wait.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ impl Drop for rcl_wait_set_t {
5959
}
6060
}
6161

62+
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
63+
// they are running in. Therefore, this type can be safely sent to another thread.
64+
unsafe impl Send for rcl_wait_set_t {}
65+
66+
// SAFETY: While the rcl_wait_set_t does have some interior mutability (because it has
67+
// members of non-const pointer type), this interior mutability is hidden/not used by
68+
// the WaitSet type. Therefore, sharing &WaitSet between threads does not risk data races.
69+
unsafe impl Sync for WaitSet {}
70+
6271
impl WaitSet {
6372
/// Creates a new wait set.
6473
///
@@ -287,3 +296,17 @@ impl WaitSet {
287296
Ok(ready_entities)
288297
}
289298
}
299+
300+
#[cfg(test)]
301+
mod tests {
302+
use super::*;
303+
304+
fn assert_send<T: Send>() {}
305+
fn assert_sync<T: Sync>() {}
306+
307+
#[test]
308+
fn wait_set_is_send_and_sync() {
309+
assert_send::<WaitSet>();
310+
assert_sync::<WaitSet>();
311+
}
312+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use rclrs::{Client, Service};
2+
3+
fn assert_send<T: Send>() {}
4+
fn assert_sync<T: Sync>() {}
5+
6+
#[test]
7+
fn client_is_send_and_sync() {
8+
assert_send::<Client<test_msgs::srv::Arrays>>();
9+
assert_sync::<Client<test_msgs::srv::Arrays>>();
10+
}
11+
12+
#[test]
13+
fn service_is_send_and_sync() {
14+
assert_send::<Service<test_msgs::srv::Arrays>>();
15+
assert_sync::<Service<test_msgs::srv::Arrays>>();
16+
}

rclrs_tests/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
#![cfg(test)]
22

3+
mod client_service_tests;
34
mod graph_tests;
5+
mod pub_sub_tests;

rclrs_tests/src/pub_sub_tests.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use rclrs::{LoanedMessage, Publisher, ReadOnlyLoanedMessage, Subscription};
2+
3+
fn assert_send<T: Send>() {}
4+
fn assert_sync<T: Sync>() {}
5+
6+
#[test]
7+
fn publisher_is_send_and_sync() {
8+
assert_send::<Publisher<test_msgs::msg::BoundedSequences>>();
9+
assert_sync::<Publisher<test_msgs::msg::BoundedSequences>>();
10+
}
11+
12+
#[test]
13+
fn subscription_is_send_and_sync() {
14+
assert_send::<Subscription<test_msgs::msg::BoundedSequences>>();
15+
assert_sync::<Subscription<test_msgs::msg::BoundedSequences>>();
16+
}
17+
18+
#[test]
19+
fn loaned_message_is_send_and_sync() {
20+
assert_send::<LoanedMessage<test_msgs::msg::rmw::BoundedSequences>>();
21+
assert_sync::<LoanedMessage<test_msgs::msg::rmw::BoundedSequences>>();
22+
}
23+
24+
#[test]
25+
fn readonly_loaned_message_is_send_and_sync() {
26+
assert_send::<ReadOnlyLoanedMessage<test_msgs::msg::rmw::BoundedSequences>>();
27+
assert_sync::<ReadOnlyLoanedMessage<test_msgs::msg::rmw::BoundedSequences>>();
28+
}

0 commit comments

Comments
 (0)