Skip to content
14 changes: 7 additions & 7 deletions include/fastdds/dds/core/policy/QosPolicies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1729,27 +1729,27 @@ class ResourceLimitsQosPolicy : public Parameter_t, public QosPolicy
* @brief Specifies the maximum number of data-samples the DataWriter (or DataReader) can manage across all the
* instances associated with it. Represents the maximum samples the middleware can store for any one DataWriter
* (or DataReader). <br>
* Value less or equal to 0 means infinite resources. By default, 5000.
* Value less or equal to 0 means infinite resources. By default, LENGTH_UNLIMITED.
*
* @warning It is inconsistent if `max_samples < (max_instances * max_samples_per_instance)`.
*/
int32_t max_samples;
/**
* @brief Represents the maximum number of instances DataWriter (or DataReader) can manage. <br>
* Value less or equal to 0 means infinite resources. By default, 10.
* Value less or equal to 0 means infinite resources. By default, LENGTH_UNLIMITED.
*
* @warning It is inconsistent if `(max_instances * max_samples_per_instance) > max_samples`.
*/
int32_t max_instances;
/**
* @brief Represents the maximum number of samples of any one instance a DataWriter(or DataReader) can manage. <br>
* Value less or equal to 0 means infinite resources. By default, 400.
* Value less or equal to 0 means infinite resources. By default, LENGTH_UNLIMITED.
*
* @warning It is inconsistent if `(max_instances * max_samples_per_instance) > max_samples`.
*/
int32_t max_samples_per_instance;
/**
* @brief Number of samples currently allocated. <br>
* @brief Number of samples initially allocated. <br>
* By default, 100.
*/
int32_t allocated_samples;
Expand All @@ -1765,9 +1765,9 @@ class ResourceLimitsQosPolicy : public Parameter_t, public QosPolicy
FASTDDS_EXPORTED_API ResourceLimitsQosPolicy()
: Parameter_t(PID_RESOURCE_LIMITS, 4 * 5)
, QosPolicy(false)
, max_samples(5000)
, max_instances(10)
, max_samples_per_instance(400)
, max_samples(LENGTH_UNLIMITED)
, max_instances(LENGTH_UNLIMITED)
, max_samples_per_instance(LENGTH_UNLIMITED)
, allocated_samples(100)
, extra_samples(1)
{
Expand Down
12 changes: 10 additions & 2 deletions src/cpp/fastdds/publisher/DataWriterHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <fastdds/rtps/common/Time_t.hpp>
#include <fastdds/rtps/writer/RTPSWriter.hpp>

#include <rtps/history/HistoryAttributesExtension.hpp>
#include <rtps/writer/BaseWriter.hpp>

namespace eprosima {
Expand All @@ -51,10 +52,17 @@ HistoryAttributes DataWriterHistory::to_history_attributes(
max_samples = history_qos.depth;
if (topic_kind != NO_KEY)
{
max_samples *= resource_limits_qos.max_instances;
if (0 < resource_limits_qos.max_instances)
{
max_samples *= resource_limits_qos.max_instances;
}
else
{
max_samples = LENGTH_UNLIMITED;
}
}

initial_samples = std::min(initial_samples, max_samples);
initial_samples = get_min_max_samples(initial_samples, max_samples);
}

return HistoryAttributes(mempolicy, payloadMaxSize, initial_samples, max_samples, extra_samples);
Expand Down
37 changes: 25 additions & 12 deletions src/cpp/fastdds/publisher/DataWriterImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,20 @@ ReturnCode_t DataWriterImpl::enable()
datasharing.add_domain_id(utils::default_domain_id());
}
w_att.endpoint.set_data_sharing_configuration(datasharing);

// Update pool config for KEEP_ALL when max_samples is infinite
if ((0 == pool_config_.maximum_size) && (KEEP_ALL_HISTORY_QOS == qos_.history().kind))
{
// Override infinite with old default value for max_samples + extra samples
pool_config_.maximum_size = 5000;
if (0 < qos_.resource_limits().extra_samples)
{
pool_config_.maximum_size += static_cast<uint32_t>(qos_.resource_limits().extra_samples);
}
EPROSIMA_LOG_ERROR(DATA_WRITER,
"DataWriter with KEEP_ALL history and infinite max_samples is not compatible with DataSharing. "
"Setting max_samples to " << pool_config_.maximum_size);
}
}
else
{
Expand Down Expand Up @@ -2124,31 +2138,30 @@ ReturnCode_t DataWriterImpl::check_qos(
qos.resource_limits().max_samples_per_instance > 0 &&
qos.history().depth > qos.resource_limits().max_samples_per_instance)
{
EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
"HISTORY DEPTH '" << qos.history().depth <<
"' is inconsistent with max_samples_per_instance: '" << qos.resource_limits().max_samples_per_instance <<
"'. Consistency rule: depth <= max_samples_per_instance." <<
" Effectively using max_samples_per_instance as depth.");
EPROSIMA_LOG_ERROR(RTPS_QOS_CHECK,
"HISTORY DEPTH '" << qos.history().depth << "' is higher than max_samples_per_instance " <<
"'" << qos.resource_limits().max_samples_per_instance << "'.");
return RETCODE_INCONSISTENT_POLICY;
}
return RETCODE_OK;
}

ReturnCode_t DataWriterImpl::check_allocation_consistency(
const DataWriterQos& qos)
{
if ((qos.resource_limits().max_samples > 0) &&
(qos.resource_limits().max_samples <
(qos.resource_limits().max_instances * qos.resource_limits().max_samples_per_instance)))
if ((qos.resource_limits().max_instances <= 0 || qos.resource_limits().max_samples_per_instance <= 0) &&
(qos.resource_limits().max_samples > 0))
{
EPROSIMA_LOG_ERROR(DDS_QOS_CHECK,
"max_samples should be greater than max_instances * max_samples_per_instance");
"max_samples should be infinite when max_instances or max_samples_per_instance are infinite");
return RETCODE_INCONSISTENT_POLICY;
}
if ((qos.resource_limits().max_instances <= 0 || qos.resource_limits().max_samples_per_instance <= 0) &&
(qos.resource_limits().max_samples > 0))
if ((qos.resource_limits().max_samples > 0) &&
(qos.resource_limits().max_samples <
(qos.resource_limits().max_instances * qos.resource_limits().max_samples_per_instance)))
{
EPROSIMA_LOG_ERROR(DDS_QOS_CHECK,
"max_samples should be infinite when max_instances or max_samples_per_instance are infinite");
"max_samples should be greater than max_instances * max_samples_per_instance");
return RETCODE_INCONSISTENT_POLICY;
}
return RETCODE_OK;
Expand Down
23 changes: 11 additions & 12 deletions src/cpp/fastdds/subscriber/DataReaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1620,31 +1620,30 @@ ReturnCode_t DataReaderImpl::check_qos(
qos.resource_limits().max_samples_per_instance > 0 &&
qos.history().depth > qos.resource_limits().max_samples_per_instance)
{
EPROSIMA_LOG_WARNING(RTPS_QOS_CHECK,
"HISTORY DEPTH '" << qos.history().depth <<
"' is inconsistent with max_samples_per_instance: '" << qos.resource_limits().max_samples_per_instance <<
"'. Consistency rule: depth <= max_samples_per_instance." <<
" Effectively using max_samples_per_instance as depth.");
EPROSIMA_LOG_ERROR(RTPS_QOS_CHECK,
"HISTORY DEPTH '" << qos.history().depth << "' is higher than max_samples_per_instance " <<
"'" << qos.resource_limits().max_samples_per_instance << "'.");
return RETCODE_INCONSISTENT_POLICY;
}
return RETCODE_OK;
}

ReturnCode_t DataReaderImpl::check_allocation_consistency(
const DataReaderQos& qos)
{
if ((qos.resource_limits().max_samples > 0) &&
(qos.resource_limits().max_samples <
(qos.resource_limits().max_instances * qos.resource_limits().max_samples_per_instance)))
if ((qos.resource_limits().max_instances <= 0 || qos.resource_limits().max_samples_per_instance <= 0) &&
(qos.resource_limits().max_samples > 0))
{
EPROSIMA_LOG_ERROR(DDS_QOS_CHECK,
"max_samples should be greater than max_instances * max_samples_per_instance");
"max_samples should be infinite when max_instances or max_samples_per_instance are infinite");
return RETCODE_INCONSISTENT_POLICY;
}
if ((qos.resource_limits().max_instances <= 0 || qos.resource_limits().max_samples_per_instance <= 0) &&
(qos.resource_limits().max_samples > 0))
if ((qos.resource_limits().max_samples > 0) &&
(qos.resource_limits().max_samples <
(qos.resource_limits().max_instances * qos.resource_limits().max_samples_per_instance)))
{
EPROSIMA_LOG_ERROR(DDS_QOS_CHECK,
"max_samples should be infinite when max_instances or max_samples_per_instance are infinite");
"max_samples should be greater than max_instances * max_samples_per_instance");
return RETCODE_INCONSISTENT_POLICY;
}
return RETCODE_OK;
Expand Down
11 changes: 9 additions & 2 deletions src/cpp/fastdds/subscriber/history/DataReaderHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,16 @@ DataReaderHistory::DataReaderHistory(
{
resource_limited_qos_.max_instances = 1;
resource_limited_qos_.max_samples_per_instance = resource_limited_qos_.max_samples;
key_changes_allocation_.initial = resource_limited_qos_.allocated_samples;
key_changes_allocation_.maximum = resource_limited_qos_.max_samples;

if (0 < resource_limited_qos_.allocated_samples)
{
key_changes_allocation_.initial = resource_limited_qos_.allocated_samples;
}

if (resource_limited_qos_.max_samples_per_instance < std::numeric_limits<int32_t>::max())
{
key_changes_allocation_.maximum = resource_limited_qos_.max_samples_per_instance;
}
instances_.emplace(c_InstanceHandle_Unknown,
std::make_shared<DataReaderInstance>(key_changes_allocation_, key_writers_allocation_));
data_available_instances_[c_InstanceHandle_Unknown] = instances_[c_InstanceHandle_Unknown];
Expand Down
15 changes: 15 additions & 0 deletions src/cpp/rtps/history/HistoryAttributesExtension.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ static inline ResourceLimitedContainerConfig resource_limits_from_history(
};
}

/**
* Get the minimum value between two sample counts, considering that <= 0 means unlimited.
*
* @param a First sample count.
* @param b Second sample count.
*
* @return Minimum sample count.
*/
static constexpr int32_t get_min_max_samples(
int32_t a,
int32_t b)
{
return (0 < a && 0 < b) ? (a < b ? a : b) : (0 < a ? a : b);
}

} // namespace rtps
} // namespace fastdds
} // namespace eprosima
Expand Down
3 changes: 3 additions & 0 deletions test/blackbox/common/BlackboxTestsReliability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ void reliability_disable_heartbeat_piggyback(
writer.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS)
.history_kind(eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS)
.history_depth(1)
.resource_limits_max_samples_per_instance(1)
.resource_limits_max_instances(10)
.resource_limits_max_samples(10)
.heartbeat_period_seconds(180000)
.disable_heartbeat_piggyback(disable_heartbeat_piggyback)
.disable_builtin_transport()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ class DataWriterHistory : public WriterHistory
max_samples = history_qos.depth;
if (topic_kind != NO_KEY)
{
max_samples *= resource_limits_qos.max_instances;
if (0 < resource_limits_qos.max_instances)
{
max_samples *= resource_limits_qos.max_instances;
}
else
{
max_samples = std::numeric_limits<int32_t>::max();
}
}

initial_samples = std::min(initial_samples, max_samples);
Expand Down
Loading
Loading