Skip to content

Commit 8d6ab51

Browse files
committed
fix(ros2): copy serialized buffers before callback return
1 parent d834019 commit 8d6ab51

2 files changed

Lines changed: 17 additions & 12 deletions

File tree

middlewares/ros2/include/ros2_subscription_wrapper.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,9 @@ class SubscriptionManager {
8686
/**
8787
* Subscribe with a zero-copy (ABI v1.2) callback.
8888
*
89-
* Fast path (no depth compression): retains the rclcpp::SerializedMessage
90-
* shared_ptr and hands the recorder a pointer into its `buffer` along with
91-
* a release function that drops the shared_ptr. No payload copy happens
92-
* between rcl and the recorder's worker queue.
89+
* Fast path (no depth compression): copies the rclcpp::SerializedMessage
90+
* payload into plugin-owned storage before returning from the ROS callback,
91+
* then hands the recorder that owned buffer plus a release function.
9392
*
9493
* Compression path (depth_compression.enabled): transparently falls back
9594
* to the v1.x copy semantics internally (the compressor allocates a new

middlewares/ros2/src/ros2_subscription_wrapper.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,21 +247,27 @@ bool SubscriptionManager::subscribe_v2(
247247
}
248248
#endif
249249

250-
// Zero-copy pass-through: hand the recorder a pointer into the rcl
251-
// buffer and a holder that keeps the SerializedMessage alive. The
252-
// release function deletes the heap-allocated shared_ptr holder,
253-
// which in turn drops the last refcount (or whatever the refcount
254-
// is at that point) on the SerializedMessage.
255-
auto* holder = new std::shared_ptr<rclcpp::SerializedMessage>(msg);
250+
// Copy the serialized payload into plugin-owned storage before
251+
// returning from the ROS callback. Holding the rclcpp
252+
// SerializedMessage in Axon's queues can exhaust DDS/rclcpp receive
253+
// buffers when recorder batching or writer backlog retains many
254+
// messages, throttling high-rate topics before they reach Axon.
256255
const auto& raw = msg->get_rcl_serialized_message();
256+
auto* holder = new std::vector<uint8_t>();
257+
if (raw.buffer != nullptr && raw.buffer_length > 0) {
258+
holder->assign(raw.buffer, raw.buffer + raw.buffer_length);
259+
}
260+
if (holder->empty()) {
261+
holder->resize(1);
262+
}
257263
callback(
258264
topic_name,
259265
message_type,
260-
raw.buffer,
266+
holder->data(),
261267
raw.buffer_length,
262268
timestamp,
263269
+[](void* p) {
264-
delete static_cast<std::shared_ptr<rclcpp::SerializedMessage>*>(p);
270+
delete static_cast<std::vector<uint8_t>*>(p);
265271
},
266272
holder
267273
);

0 commit comments

Comments
 (0)