Skip to content

Commit 5cce85f

Browse files
committed
Complete implementation of ActionServer::publish_status()
This skips some of the steps that rclcpp performs, as they appear to be unnecessary. Testing should reveal whether that's true or not.
1 parent 2c8cd97 commit 5cce85f

File tree

1 file changed

+14
-31
lines changed

1 file changed

+14
-31
lines changed

rclrs/src/action/server.rs

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
error::{RclReturnCode, ToResult},
44
rcl_bindings::*,
55
wait::WaitableNumEntities,
6-
Clock, Node, RclrsError, ENTITY_LIFECYCLE_MUTEX,
6+
Clock, DropGuard, Node, RclrsError, ENTITY_LIFECYCLE_MUTEX,
77
};
88
use rosidl_runtime_rs::{Action, Message, Service};
99
use std::{
@@ -286,43 +286,26 @@ where
286286
}
287287

288288
fn publish_status(&self) -> Result<(), RclrsError> {
289-
// We need to hold the lock across this entire method because
290-
// rcl_action_server_get_goal_handles() returns an internal pointer to the
291-
// goal data.
292-
let handle = &*self.handle.lock();
293-
294-
let mut goal_handles = std::ptr::null_mut::<*mut rcl_action_goal_handle_t>();
295-
let mut num_goal_handles = 0;
296-
unsafe {
297-
// SAFETY: The action server is locked for this entire function, ensuring that the
298-
// goal_handles array remains valid, unless rcl_shutdown is called. However, that is
299-
// outside our control.
300-
rcl_action_server_get_goal_handles(handle, &mut goal_handles, &mut num_goal_handles)
301-
}.ok()?;
302-
303-
let mut goal_statuses = unsafe {
289+
let mut goal_statuses = DropGuard::new(unsafe {
304290
// SAFETY: No preconditions
305291
rcl_action_get_zero_initialized_goal_status_array()
306-
};
292+
}, |mut goal_status| unsafe {
293+
// SAFETY: The goal_status array is either zero-initialized and empty or populated by
294+
// `rcl_action_get_goal_status_array`. In either case, it can be safely finalized.
295+
rcl_action_goal_status_array_fini(&mut goal_status);
296+
});
297+
307298
unsafe {
308299
// SAFETY: The action server is locked through the handle and goal_statuses is
309300
// zero-initialized.
310-
rcl_action_get_goal_status_array(handle, &mut goal_statuses)
301+
rcl_action_get_goal_status_array(&*self.handle.lock(), &mut *goal_statuses)
311302
}.ok()?;
312-
// TODO(nwn): Ensure that rcl_action_goal_status_array_fini() is always called on exit.
313-
314-
let goal_status_slice = unsafe {
315-
// SAFETY: rcl_action_get_goal_status_array initializes goal_statues.msg.status_list as
316-
// an array of goal statuses with the indicated size. The memory backing this array is
317-
// not modified by anything else during the lifetime of the slice.
318-
std::slice::from_raw_parts(goal_statuses.msg.status_list.data, goal_statuses.msg.status_list.size)
319-
};
320-
for goal_status in goal_status_slice {
321-
// Copy into the correct message type to pass to rcl_action_publish_status().
322-
}
323-
// Call rcl_action_publish_status().
324303

325-
todo!()
304+
unsafe {
305+
// SAFETY: The action server is locked through the handle and goal_statuses.msg is a
306+
// valid `action_msgs__msg__GoalStatusArray` by construction.
307+
rcl_action_publish_status(&*self.handle.lock(), &goal_statuses.msg as *const _ as *const std::ffi::c_void)
308+
}.ok()
326309
}
327310
}
328311

0 commit comments

Comments
 (0)