Skip to content

Commit b0e3738

Browse files
author
Mauro Passerino
committed
Fix data race in QOSEventHandlerBase
Both QOSEventHandler 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 ~QOSEventHandlerBase wants to access the listener after it has been destroyed. The QOSEventHandler stores a shared_ptr of its associated pub/sub. But since we were clearing the listener event callbacks on the base class destructor ~QOSEventHandlerBase, 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 ~QOSEventHandler instead of ~QOSEventHandlerBase fixes the race, since the pub/sub are still valid. Signed-off-by: Mauro Passerino <[email protected]>
1 parent 679ab77 commit b0e3738

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

rclcpp/include/rclcpp/qos_event.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,16 @@ class QOSEventHandler : public QOSEventHandlerBase
246246
}
247247
}
248248

249+
~QOSEventHandler()
250+
{
251+
// Since the rmw event listener holds a reference to the
252+
// "on ready" callback, we need to clear it on destruction of this class.
253+
// This clearing is not needed for other rclcpp entities like pub/subs, since
254+
// they do own the underlying rmw entities, which are destroyed
255+
// on their rclcpp destructors, thus no risk of dangling pointers.
256+
clear_on_ready_callback();
257+
}
258+
249259
/// Take data so that the callback cannot be scheduled again
250260
std::shared_ptr<void>
251261
take_data() override

rclcpp/src/rclcpp/qos_event.cpp

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

3636
QOSEventHandlerBase::~QOSEventHandlerBase()
3737
{
38-
// Since the rmw event listener holds a reference to
39-
// this callback, we need to clear it on destruction of this class.
40-
// This clearing is not needed for other rclcpp entities like pub/subs, since
41-
// they do own the underlying rmw entities, which are destroyed
42-
// on their rclcpp destructors, thus no risk of dangling pointers.
43-
clear_on_ready_callback();
44-
4538
if (rcl_event_fini(&event_handle_) != RCL_RET_OK) {
4639
RCUTILS_LOG_ERROR_NAMED(
4740
"rclcpp",

0 commit comments

Comments
 (0)