From 68e3e55c2f58a95ab48459eb59a66cb800696fed Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 10 Sep 2019 15:51:25 +0200 Subject: [PATCH] ddsi_sertopic_free_samples expects an array So dds_read/dds_take should pass it the address of the first pointer, rather than the first pointer itself, or the freeing of memory allocated for samples because of an outstanding loan will crash. Add a test that reliable detects this case when no other participants are around. Signed-off-by: Erik Boasson --- src/core/ddsc/src/dds_read.c | 2 +- src/core/ddsc/tests/builtin_topics.c | 32 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/core/ddsc/src/dds_read.c b/src/core/ddsc/src/dds_read.c index a2b1584..ad766a5 100644 --- a/src/core/ddsc/src/dds_read.c +++ b/src/core/ddsc/src/dds_read.c @@ -130,7 +130,7 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition, if (nodata_cleanups & NC_CLEAR_LOAN_OUT) rd->m_loan_out = false; if (nodata_cleanups & NC_FREE_BUF) - ddsi_sertopic_free_samples (rd->m_topic->m_stopic, buf[0], maxs, DDS_FREE_ALL); + ddsi_sertopic_free_samples (rd->m_topic->m_stopic, buf, maxs, DDS_FREE_ALL); if (nodata_cleanups & NC_RESET_BUF) buf[0] = NULL; ddsrt_mutex_unlock (&rd->m_entity.m_mutex); diff --git a/src/core/ddsc/tests/builtin_topics.c b/src/core/ddsc/tests/builtin_topics.c index e4d2ff0..747b1d2 100644 --- a/src/core/ddsc/tests/builtin_topics.c +++ b/src/core/ddsc/tests/builtin_topics.c @@ -308,3 +308,35 @@ CU_Test(ddsc_builtin_topics, builtin_qos, .init = setup, .fini = teardown) CU_ASSERT_FATAL(dds_sub_subscriber > 0); check_default_qos_of_builtin_entity(dds_sub_subscriber, 0); } + +CU_Test(ddsc_builtin_topics, read_nothing) +{ + dds_entity_t pp; + dds_entity_t rd; + dds_return_t ret; + dds_sample_info_t si; + void *raw1, *raw2; + int32_t n1, n2; + + pp = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); + CU_ASSERT_FATAL (pp > 0); + rd = dds_create_reader (pp, DDS_BUILTIN_TOPIC_DCPSSUBSCRIPTION, NULL, NULL); + CU_ASSERT_FATAL (rd > 0); + + /* Can't guarantee there's no other process around with a publication, but + we can take until nothing remains. The point is checking handling of + freeing memory when a loan was outstanding, memory had to be allocated, + and subsequently had to be freed because of an absence of data. */ + raw1 = raw2 = NULL; + n1 = dds_take (rd, &raw1, &si, 1, 1); + CU_ASSERT_FATAL (n1 >= 0); + n2 = dds_take (rd, &raw2, &si, 1, 1); + CU_ASSERT_FATAL (n2 >= 0); + ret = dds_return_loan (rd, &raw1, n1); + CU_ASSERT_FATAL (ret == 0); + ret = dds_return_loan (rd, &raw2, n2); + CU_ASSERT_FATAL (ret == 0); + + ret = dds_delete (pp); + CU_ASSERT_FATAL (ret == 0); +}