-
Notifications
You must be signed in to change notification settings - Fork 120
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
Fix leak if client reponse is never taken #201
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,8 @@ | |
|
||
#include <atomic> | ||
#include <list> | ||
#include <memory> | ||
#include <utility> | ||
|
||
#include "fastcdr/FastBuffer.h" | ||
|
||
|
@@ -43,7 +45,7 @@ typedef struct CustomClientInfo | |
typedef struct CustomClientResponse | ||
{ | ||
eprosima::fastrtps::rtps::SampleIdentity sample_identity_; | ||
eprosima::fastcdr::FastBuffer * buffer_; | ||
std::unique_ptr<eprosima::fastcdr::FastBuffer> buffer_; | ||
|
||
CustomClientResponse() | ||
: buffer_(nullptr) {} | ||
|
@@ -63,10 +65,10 @@ class ClientListener : public eprosima::fastrtps::SubscriberListener | |
assert(sub); | ||
|
||
CustomClientResponse response; | ||
response.buffer_ = new eprosima::fastcdr::FastBuffer(); | ||
response.buffer_.reset(new eprosima::fastcdr::FastBuffer()); | ||
eprosima::fastrtps::SampleInfo_t sinfo; | ||
|
||
if (sub->takeNextData(response.buffer_, &sinfo)) { | ||
if (sub->takeNextData(response.buffer_.get(), &sinfo)) { | ||
if (eprosima::fastrtps::rtps::ALIVE == sinfo.sampleKind) { | ||
response.sample_identity_ = sinfo.related_sample_identity; | ||
|
||
|
@@ -75,15 +77,15 @@ class ClientListener : public eprosima::fastrtps::SubscriberListener | |
|
||
if (conditionMutex_ != nullptr) { | ||
std::unique_lock<std::mutex> clock(*conditionMutex_); | ||
list.push_back(response); | ||
list.emplace_back(std::move(response)); | ||
// the change to list_has_data_ needs to be mutually exclusive with | ||
// rmw_wait() which checks hasData() and decides if wait() needs to | ||
// be called | ||
list_has_data_.store(true); | ||
clock.unlock(); | ||
conditionVariable_->notify_one(); | ||
} else { | ||
list.push_back(response); | ||
list.emplace_back(std::move(response)); | ||
list_has_data_.store(true); | ||
} | ||
} | ||
|
@@ -100,19 +102,19 @@ class ClientListener : public eprosima::fastrtps::SubscriberListener | |
if (conditionMutex_ != nullptr) { | ||
std::unique_lock<std::mutex> clock(*conditionMutex_); | ||
if (!list.empty()) { | ||
response = list.front(); | ||
response = std::move(list.front()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this move is necessary because of the unique_ptr inside the response, right? This is potentially dangerous because the list is afterwards invalid. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
list.pop_front(); | ||
list_has_data_.store(!list.empty()); | ||
} | ||
} else { | ||
if (!list.empty()) { | ||
response = list.front(); | ||
response = std::move(list.front()); | ||
list.pop_front(); | ||
list_has_data_.store(!list.empty()); | ||
} | ||
} | ||
|
||
return response; | ||
return std::move(response); | ||
} | ||
|
||
void | ||
|
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.
why does this have to be a heap allocation in the first place?
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.
I hadn't thought of that. It shouldn't need to be. I just tried changing it to an instance, but I can't get around double-free errors.
That class uses raw pointers, but it does not implement a copy constructor or move constructor nor does it delete them. As a result the same pointer is freed when
CustomClientResponse
is removed from the list and whenCustomClientResponse
is destructed. I'll make an issue on the FastCDR repo.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.
eProsima/Fast-CDR#19