Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread safe node.destroy_* #319

Merged
merged 16 commits into from
May 1, 2019
Merged

Thread safe node.destroy_* #319

merged 16 commits into from
May 1, 2019

Conversation

sloretz
Copy link
Contributor

@sloretz sloretz commented Apr 24, 2019

Follow up to #318 and #330. This PR applies the changes done to Subscription to the rest of the entities on the node so they can all be destroyed safely.

  • destroy_publisher
  • destroy_client
  • destroy_service
  • destroy_timer
    • Clock used by timer safely destroyed
  • destroy_guard_condition

Not done in this PR. These might require a change to the waitable API.

  • action server
  • action client

@sloretz sloretz added the in progress Actively being worked on (Kanban column) label Apr 24, 2019
@sloretz sloretz self-assigned this Apr 24, 2019
@sloretz sloretz force-pushed the sloretz/thread_safe_destroy branch from 7ba0972 to 0e8cda0 Compare April 25, 2019 22:17
@sloretz
Copy link
Contributor Author

sloretz commented Apr 25, 2019

I think I have to include destroy_node in this PR. This approach can change the order that entities get shut down.

# In another thread an executor is spinning
# srv destruction delayed because executor is waiting on service
node.destroy_service(srv)

# node is destroyed instantly; service still not destroyed because it's being used by executor
node.destroy_node()

# When executor shuts down the service is no longer being used, so it's destroyed
# since the node was destroyed first the service will segfault in rmw_fastrtps
executor.shutdown()

I'm thinking of chaining handles so that node.destroy_node() destroy's all node entities before allowing itself to be destroyed.

Publisher now uses Handle
pub.publisher_handle -> pub.handle
Added test for publisher destruction
Added rclpy_publisher_t to replace rcl_publisher_t

Signed-off-by: Shane Loretz<sloretz@openrobotics.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Client now uses Handle
Client.client_handle and client_pointer replaced by client.handle
rclpy_destroy_entity no longer destroy's clients
Added test for client destruction
Client capsule uses rclpy_client_t instead of rcl_client_t

Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
@sloretz sloretz force-pushed the sloretz/thread_safe_destroy branch from 052b0ed to e4ca965 Compare April 30, 2019 20:26
self._guard_condition = gc
self._guard_condition_handle = gc_handle
self._guard = GuardCondition(
callback=None, callback_group=None, context=self._context)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reusing GuardCondition to reuse executor code that uses guard_condition.handle

Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
@sloretz sloretz added in review Waiting for review (Kanban column) and removed in progress Actively being worked on (Kanban column) labels Apr 30, 2019
@sloretz
Copy link
Contributor Author

sloretz commented Apr 30, 2019

Ready for review.

CI (testing rclpy)

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review with some feedback on parts I know :). Will do some additional review after.

rclpy/src/rclpy/_rclpy.c Show resolved Hide resolved
rclpy/src/rclpy/_rclpy.c Show resolved Hide resolved
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right, a few more review comments, mostly phrased as questions as I'm still getting a handle on how this works (pun intended).

rclpy/rclpy/node.py Outdated Show resolved Hide resolved
return True
if publisher in self.publishers:
self.publishers.remove(publisher)
publisher.destroy()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of these destroy calls, do we need to check for the InvalidHandle exception? Is that a case that can happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. Maybe this should catch it and return False?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that seems reasonable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

destroy_<entity>() catch InvalidHandle and return False in e630404

rclpy/rclpy/executors.py Show resolved Hide resolved
rclpy/rclpy/executors.py Show resolved Hide resolved
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me now, so I'll approve.

My only remaining question is whether we should open an issue for reducing the complexity here by introducing rmw_shutdown_but_not_fini for a future enhancement. Thoughts on that?

@sloretz
Copy link
Contributor Author

sloretz commented May 1, 2019

CI (testing rclpy)

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@sloretz
Copy link
Contributor Author

sloretz commented May 1, 2019

My only remaining question is whether we should open an issue for reducing the complexity here by introducing rmw_shutdown_but_not_fini for a future enhancement. Thoughts on that?

I've gone back and forth between writing the issue on rmw vs making it a higher level feature of rcl. I opened ros2/rcl#429, but the solution seems a lot more complicated than I first thought. I put it in the backlog since it feels like it needs more thought.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants