-
Notifications
You must be signed in to change notification settings - Fork 430
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
Improve Loaned messages memory handling #2624
base: rolling
Are you sure you want to change the base?
Improve Loaned messages memory handling #2624
Conversation
Instead of returning the loaned after executing the subscription, return it when the last ref of the message goes out of scope. - ros2#2401 Signed-off-by: Mauro Passerino <[email protected]>
Signed-off-by: Mauro Passerino <[email protected]>
Since Fast-DDS is our default RMW, I don't think we can move forward without fixing this somehow. So I'm going to mark this as a "draft" for now. |
@clalancette by changing the history memory policy on the FastDDS profile, the tests pass! That is, memory is not reused until all entities have returned the loans (as expected). < <historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy>
---
> <historyMemoryPolicy>DYNAMIC_REUSABLE</historyMemoryPolicy>
I'll update the PR description. |
Signed-off-by: Mauro Passerino <[email protected]>
EXPECT_TRUE(loaned_addresses_match(pub_sub_loaned, sub_loaned)); | ||
} | ||
|
||
// FastDDS: Show that the publisher gets loans from memory still in use: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there are some tests that are specific to some RMW implementation.
I'm also not sure if they are all valid unit-tests or rather "examples" showing the limitations of some RMWs.
In any case, we should run these tests only for the RMWs they matter, for example with
if (std::string(rmw_get_implementation_identifier()).find("rmw_connextdds") == 0)
{
GTEST_SKIP();
}
Hi @mauropasse , thanks for your great job. I have tried this improvement on ros2-humble with cyclonedds in our project. But things didn't go as well. Below are some code snippets. I tried to copy the loaned_msg_ptr to a dataset. The initial return of loaned_msg_ptr to iceoryx was successful. But the later can not be retruned correctly. using MSG = std_msgs::msg::Uint16;
int main(){
// some ros2 initialization
std::vector<MSG::SharedPtr> dataset;
auto sub = node->create_subscription<MSG>(
topic_name, 10,
[&data_set](MSG::SharedPtr loaned_msg_ptr) {
data_set.push_back(loaned_msg_ptr);
});
// sleep for a while to wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// after at least two subscription callback, release loaned_msg_ptr
dataset.clear();
}
This happens only when the second subscription callback come before the first loaned message is returned. Because every
I think this issue also exists in ROS2 Rolling, right? |
Related to #2401
Loaned messages can be held simultaneously by different entities:
The last reference to a loaned message has to return the loan to the RMW when the message goes out of scope. This allows for memory to be reused for future loaned messages.
The case when the user is the last holding references to the message, wasn't working as expected because the loans were returned after executing the subscription, regardless of whether the user had made copies of the message.
This PR improves the situation by introducing a custom message deleter, which calls the return loan API upon the destruction of the last reference.
Note: In this PR, the new message pointer passed to a subscription is not
const
, so the user can modify messages contents. This is likely not desired, but its useful for demonstration purposes here.On FastDDS, memory is correctly handled when using on the
FASTRTPS_DEFAULT_PROFILES_FILE
:A small fix is still required in
rmw_cyclonedds_cpp
to avoid finalizing an allocator multiple times: don't calldds_data_allocator_fini
here.In a different scenario, CycloneDDS suffers from a "double delivery issue," in which a late joiner subscription receives both interprocess and loaned transient local messages (published before its creation), before segfaulting. FastDDS does not experience this problem.
In this PR I add a unit test for testing different scenarios: