Skip to content

Commit 411dbe8

Browse files
authored
Fix data race in EventHandlerBase (ros2#2349)
Both the EventHandler and its associated pubs/subs share the same underlying rmw event listener. When a pub/sub is destroyed, the listener is destroyed. There is a data race when the ~EventHandlerBase wants to access the listener after it has been destroyed. The EventHandler stores a shared_ptr of its associated pub/sub. But since we were clearing the listener event callbacks on the base class destructor ~EventHandlerBase, the pub/sub was already destroyed, which means the rmw event listener was also destroyed, thus causing a segfault when trying to obtain it to clear the callbacks. Clearing the callbacks on ~EventHandler instead of ~EventHandlerBase avoids the race, since the pub/sub are still valid. Signed-off-by: Mauro Passerino <[email protected]>
1 parent de841d9 commit 411dbe8

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

rclcpp/include/rclcpp/event_handler.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,16 @@ class EventHandler : public EventHandlerBase
260260
}
261261
}
262262

263+
~EventHandler()
264+
{
265+
// Since the rmw event listener holds a reference to the
266+
// "on ready" callback, we need to clear it on destruction of this class.
267+
// This clearing is not needed for other rclcpp entities like pub/subs, since
268+
// they do own the underlying rmw entities, which are destroyed
269+
// on their rclcpp destructors, thus no risk of dangling pointers.
270+
clear_on_ready_callback();
271+
}
272+
263273
/// Take data so that the callback cannot be scheduled again
264274
std::shared_ptr<void>
265275
take_data() override

rclcpp/src/rclcpp/event_handler.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,6 @@ UnsupportedEventTypeException::UnsupportedEventTypeException(
3939

4040
EventHandlerBase::~EventHandlerBase()
4141
{
42-
// Since the rmw event listener holds a reference to
43-
// this callback, we need to clear it on destruction of this class.
44-
// This clearing is not needed for other rclcpp entities like pub/subs, since
45-
// they do own the underlying rmw entities, which are destroyed
46-
// on their rclcpp destructors, thus no risk of dangling pointers.
47-
clear_on_ready_callback();
48-
4942
if (rcl_event_fini(&event_handle_) != RCL_RET_OK) {
5043
RCUTILS_LOG_ERROR_NAMED(
5144
"rclcpp",

0 commit comments

Comments
 (0)