From 20fa528f443ffce864e318c070ed0a8f4383e38c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Thu, 11 Jul 2024 08:19:44 +0200 Subject: [PATCH] Fix warning about memory leak (#141) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno (cherry picked from commit 7cbeb21dc67c416c5afcdc22df00c550b2c2cb92) # Conflicts: # fastdds_python/src/swig/fastdds/dds/core/policy/QosPolicies.i # fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i # fastdds_python/test/api/test_domainparticipant.py --- .../fastdds/dds/core/policy/QosPolicies.i | 10 ++ .../utils/collections/ResourceLimitedVector.i | 117 ++++++++++++++++-- .../test/api/test_domainparticipant.py | 6 + fastdds_python/test/api/test_qos.py | 48 +++---- 4 files changed, 148 insertions(+), 33 deletions(-) diff --git a/fastdds_python/src/swig/fastdds/dds/core/policy/QosPolicies.i b/fastdds_python/src/swig/fastdds/dds/core/policy/QosPolicies.i index 00d2f46c..2259c6b3 100644 --- a/fastdds_python/src/swig/fastdds/dds/core/policy/QosPolicies.i +++ b/fastdds_python/src/swig/fastdds/dds/core/policy/QosPolicies.i @@ -58,6 +58,7 @@ namespace dds { } } +<<<<<<< HEAD %inline %{ class OctetResourceLimitedVectorStopIterator {}; class OctetResourceLimitedVectorIterator { @@ -73,10 +74,13 @@ public: eprosima::fastrtps::ResourceLimitedVector::iterator end; }; %} +======= +>>>>>>> 7cbeb21 (Fix warning about memory leak (#141)) // SWIG does not support templates in the generated binding, // because not all output languages support them // We must explicitly declare the specializations of the templates +<<<<<<< HEAD %template(OctetResourceLimitedVector) eprosima::fastrtps::ResourceLimitedVector; %include "fastdds/dds/core/policy/QosPolicies.hpp" @@ -143,6 +147,12 @@ public: } } +======= +resource_limited_vector_template(OctetResourceLimitedVector, eprosima::fastdds::rtps::octet) + +%include "fastdds/dds/core/policy/QosPolicies.hpp" + +>>>>>>> 7cbeb21 (Fix warning about memory leak (#141)) %exception eprosima::fastdds::dds::PartitionQosPolicy::__getitem__ { try diff --git a/fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i b/fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i index 2b9c48df..6260f808 100644 --- a/fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i +++ b/fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i @@ -16,6 +16,8 @@ #include "fastrtps/utils/collections/ResourceLimitedVector.hpp" %} +%include "exception.i" + // Operator[] is ignored by SWIG because it does not map correctly to target languages // mostly because of its dual getter/setter nature // We can ignore them and extend to make the getter and setter methods explicit and break the overload @@ -26,9 +28,16 @@ // it seems that SWIG handles them differently and compilation fails // when trying to create a pointer to a reference and/or calling new for a reference // We rewrite them in terms of pointer results +<<<<<<< HEAD:fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i %ignore eprosima::fastrtps::ResourceLimitedVector::at; %ignore eprosima::fastrtps::ResourceLimitedVector::front; %ignore eprosima::fastrtps::ResourceLimitedVector::back; +======= +%ignore eprosima::fastdds::ResourceLimitedVector::at; +%ignore eprosima::fastdds::ResourceLimitedVector::front; +%ignore eprosima::fastdds::ResourceLimitedVector::back; +%ignore eprosima::fastdds::ResourceLimitedVector::push_back; +>>>>>>> 7cbeb21 (Fix warning about memory leak (#141)):fastdds_python/src/swig/fastdds/utils/collections/ResourceLimitedVector.i // Initializer lists are note supported in SWIG. Ignore the method %ignore eprosima::fastrtps::ResourceLimitedVector::assign(std::initializer_list); @@ -37,28 +46,118 @@ // and SWIG does not support it in any case %ignore eprosima::fastrtps::ResourceLimitedVector::operator const collection_type&; +%exception eprosima::fastdds::ResourceLimitedVector::__getitem__ +{ + try + { + $action + } + catch(std::out_of_range) + { + SWIG_exception(SWIG_IndexError, "Index out of bounds"); + } +} + +<<<<<<< HEAD:fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i %extend eprosima::fastrtps::ResourceLimitedVector { pointer at(size_type pos) +======= +%extend eprosima::fastdds::ResourceLimitedVector { + + size_t __len__() const +>>>>>>> 7cbeb21 (Fix warning about memory leak (#141)):fastdds_python/src/swig/fastdds/utils/collections/ResourceLimitedVector.i { - return &($self->at(pos)); - } - pointer front() - { - return &($self->front()); + return self->size(); } - pointer back() + + value_type __getitem__(int i) { - return &($self->back()); + if (self->size() <= i) + { + throw std::out_of_range("Index out of bounds"); + } + return (*self)[i]; } pointer getitem(size_type n) { return &($self->operator[](n)); } - void setitem(size_type n, const_pointer v) { - $self->operator[](n) = *v; + void setitem(size_type n, value_type v) { + $self->operator[](n) = v; + } + + void append(value_type v) { + $self->push_back(v); } } +<<<<<<< HEAD:fastdds_python/src/swig/fastrtps/utils/collections/ResourceLimitedVector.i %include "fastrtps/utils/collections/ResourceLimitedVector.hpp" +======= + +%include "fastdds/utils/collections/ResourceLimitedVector.hpp" + +%define resource_limited_vector_template(name_, value_type_) +%inline %{ + class name_ ## StopIterator {}; + class name_ ## Iterator + { + public: + name_ ## Iterator( + typename eprosima::fastdds::ResourceLimitedVector::iterator _cur, + typename eprosima::fastdds::ResourceLimitedVector::iterator _end) + : cur(_cur) + , end(_end) + { + } + + name_ ## Iterator* __iter__() + { + return this; + } + typename eprosima::fastdds::ResourceLimitedVector::iterator cur; + typename eprosima::fastdds::ResourceLimitedVector::iterator end; + }; +%} + +%exception name_ ## Iterator::__next__ { + try + { + $action // calls %extend function __next__() below + } + catch (name_ ## StopIterator) + { + PyErr_SetString(PyExc_StopIteration, "End of iterator"); + return nullptr; + } +} + +%extend name_ ## Iterator +{ + value_type_ __next__() + { + if ($self->cur != $self->end) + { + // dereference the iterator and return reference to the object, + // after that it increments the iterator + return *$self->cur++; + } + throw name_ ## StopIterator(); + } +} + +%template(name_) eprosima::fastdds::ResourceLimitedVector; + +%extend eprosima::fastdds::ResourceLimitedVector +{ + + name_ ## Iterator __iter__() + { + // return a constructed Iterator object + return name_ ## Iterator($self->begin(), $self->end()); + } +} +%enddef +>>>>>>> 7cbeb21 (Fix warning about memory leak (#141)):fastdds_python/src/swig/fastdds/utils/collections/ResourceLimitedVector.i diff --git a/fastdds_python/test/api/test_domainparticipant.py b/fastdds_python/test/api/test_domainparticipant.py index 1d8ea006..7ad9cb24 100644 --- a/fastdds_python/test/api/test_domainparticipant.py +++ b/fastdds_python/test/api/test_domainparticipant.py @@ -915,9 +915,15 @@ def test_get_set_qos(participant): - DomainParticipant::set_qos """ qos = fastdds.DomainParticipantQos() +<<<<<<< HEAD assert(fastdds.ReturnCode_t.RETCODE_OK == participant.get_qos(qos)) qos.user_data().push_back(1) qos.user_data().push_back(2) +======= + assert(fastdds.RETCODE_OK == participant.get_qos(qos)) + qos.user_data().append(1) + qos.user_data().append(2) +>>>>>>> 7cbeb21 (Fix warning about memory leak (#141)) assert(2 == len(qos.user_data())) assert(fastdds.ReturnCode_t.RETCODE_OK == diff --git a/fastdds_python/test/api/test_qos.py b/fastdds_python/test/api/test_qos.py index 02278dc8..817e3a21 100644 --- a/fastdds_python/test/api/test_qos.py +++ b/fastdds_python/test/api/test_qos.py @@ -82,10 +82,10 @@ def test_datareader_qos(): assert(2 == datareader_qos.resource_limits().extra_samples) # .user_data - datareader_qos.user_data().push_back(0) - datareader_qos.user_data().push_back(1) - datareader_qos.user_data().push_back(2) - datareader_qos.user_data().push_back(3) + datareader_qos.user_data().append(0) + datareader_qos.user_data().append(1) + datareader_qos.user_data().append(2) + datareader_qos.user_data().append(3) count = 1 for user_value in datareader_qos.user_data(): if 1 == count: @@ -560,10 +560,10 @@ def test_datawriter_qos(): assert(33 == datawriter_qos.lifespan().duration.nanosec) # .user_data - datawriter_qos.user_data().push_back(0) - datawriter_qos.user_data().push_back(1) - datawriter_qos.user_data().push_back(2) - datawriter_qos.user_data().push_back(3) + datawriter_qos.user_data().append(0) + datawriter_qos.user_data().append(1) + datawriter_qos.user_data().append(2) + datawriter_qos.user_data().append(3) count = 1 for user_value in datawriter_qos.user_data(): if 1 == count: @@ -873,10 +873,10 @@ def test_topic_qos(): topic_qos = fastdds.TopicQos() # .topic_data - topic_qos.topic_data().push_back(0) - topic_qos.topic_data().push_back(1) - topic_qos.topic_data().push_back(2) - topic_qos.topic_data().push_back(3) + topic_qos.topic_data().append(0) + topic_qos.topic_data().append(1) + topic_qos.topic_data().append(2) + topic_qos.topic_data().append(3) count = 1 for topic_value in topic_qos.topic_data(): if 1 == count: @@ -1091,10 +1091,10 @@ def test_subscriber_qos(): assert('Partition2' == subscriber_qos.partition()[1]) # .group_data - subscriber_qos.group_data().push_back(0) - subscriber_qos.group_data().push_back(1) - subscriber_qos.group_data().push_back(2) - subscriber_qos.group_data().push_back(3) + subscriber_qos.group_data().append(0) + subscriber_qos.group_data().append(1) + subscriber_qos.group_data().append(2) + subscriber_qos.group_data().append(3) count = 1 for group_value in subscriber_qos.group_data(): if 1 == count: @@ -1175,10 +1175,10 @@ def test_publisher_qos(): assert('Partition2' == publisher_qos.partition()[1]) # .group_data - publisher_qos.group_data().push_back(0) - publisher_qos.group_data().push_back(1) - publisher_qos.group_data().push_back(2) - publisher_qos.group_data().push_back(3) + publisher_qos.group_data().append(0) + publisher_qos.group_data().append(1) + publisher_qos.group_data().append(2) + publisher_qos.group_data().append(3) count = 1 for group_value in publisher_qos.group_data(): if 1 == count: @@ -1353,10 +1353,10 @@ def test_domain_participant_qos(): assert(not participant_qos.transport().use_builtin_transports) # .user_data - participant_qos.user_data().push_back(0) - participant_qos.user_data().push_back(1) - participant_qos.user_data().push_back(2) - participant_qos.user_data().push_back(3) + participant_qos.user_data().append(0) + participant_qos.user_data().append(1) + participant_qos.user_data().append(2) + participant_qos.user_data().append(3) count = 1 for user_value in participant_qos.user_data(): if 1 == count: