set DATA_AVAILABLE when deleting writer (#148)
Deleting a writer causes unregisters (and possibly disposes) in the rest of the network, and these updates to the instances should trigger DATA_AVAILABLE. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
b14663c173
commit
671e73ec98
2 changed files with 124 additions and 3 deletions
|
@ -1523,6 +1523,7 @@ void dds_rhc_unregister_wr (struct rhc * __restrict rhc, const struct proxy_writ
|
|||
built-in topics and in get_instance_handle, and one used internally
|
||||
for tracking registrations and unregistrations. */
|
||||
bool trigger_waitsets = false;
|
||||
bool notify_data_available = false;
|
||||
struct rhc_instance *inst;
|
||||
struct ut_hhIter iter;
|
||||
const uint64_t wr_iid = pwr_info->iid;
|
||||
|
@ -1568,16 +1569,28 @@ void dds_rhc_unregister_wr (struct rhc * __restrict rhc, const struct proxy_writ
|
|||
|
||||
TRACE ("\n");
|
||||
|
||||
notify_data_available = true;
|
||||
if (trigger_info_differs (&pre, &post, &trig_qc) && update_conditions_locked (rhc, true, &pre, &post, &trig_qc, inst))
|
||||
trigger_waitsets = true;
|
||||
assert (rhc_check_counts_locked (rhc, true, false));
|
||||
}
|
||||
}
|
||||
TRACE (")\n");
|
||||
|
||||
ddsrt_mutex_unlock (&rhc->lock);
|
||||
|
||||
if (trigger_waitsets)
|
||||
dds_entity_status_signal (&rhc->reader->m_entity);
|
||||
if (rhc->reader)
|
||||
{
|
||||
if (notify_data_available && (rhc->reader->m_entity.m_status_enable & DDS_DATA_AVAILABLE_STATUS))
|
||||
{
|
||||
ddsrt_atomic_inc32 (&rhc->n_cbs);
|
||||
dds_reader_data_available_cb (rhc->reader);
|
||||
ddsrt_atomic_dec32 (&rhc->n_cbs);
|
||||
}
|
||||
|
||||
if (trigger_waitsets)
|
||||
dds_entity_status_signal (&rhc->reader->m_entity);
|
||||
}
|
||||
}
|
||||
|
||||
void dds_rhc_relinquish_ownership (struct rhc * __restrict rhc, const uint64_t wr_iid)
|
||||
|
|
|
@ -400,7 +400,8 @@ static void
|
|||
fini_triggering_test(void)
|
||||
{
|
||||
dds_delete(g_reader);
|
||||
dds_delete(g_writer);
|
||||
if (g_writer)
|
||||
dds_delete(g_writer);
|
||||
fini_triggering_base();
|
||||
}
|
||||
|
||||
|
@ -847,6 +848,113 @@ CU_Test(ddsc_listener, data_available, .init=init_triggering_test, .fini=fini_tr
|
|||
ret = dds_read_status(g_reader, &status, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
|
||||
/* Deleting the writer causes unregisters (or dispose+unregister), and those
|
||||
should trigger DATA_AVAILABLE as well */
|
||||
cb_called = 0;
|
||||
cb_reader = 0;
|
||||
ret = dds_delete (g_writer);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
g_writer = 0;
|
||||
triggered = waitfor_cb(DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(triggered & DDS_DATA_AVAILABLE_STATUS, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(cb_reader, g_reader);
|
||||
|
||||
/* The listener should have swallowed the status. */
|
||||
ret = dds_read_status(g_subscriber, &status, DDS_DATA_ON_READERS_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
ret = dds_read_status(g_reader, &status, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
}
|
||||
|
||||
CU_Test(ddsc_listener, data_available_delete_writer, .init=init_triggering_test, .fini=fini_triggering_test)
|
||||
{
|
||||
dds_return_t ret;
|
||||
uint32_t triggered;
|
||||
uint32_t status;
|
||||
RoundTripModule_DataType sample;
|
||||
memset (&sample, 0, sizeof (sample));
|
||||
|
||||
/* We are interested in data available notifications. */
|
||||
dds_lset_data_available(g_listener, data_available_cb);
|
||||
ret = dds_set_listener(g_reader, g_listener);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
|
||||
/* Write sample, wait for the listener to swallow the status. */
|
||||
ret = dds_write(g_writer, &sample);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
triggered = waitfor_cb(DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(triggered & DDS_DATA_AVAILABLE_STATUS, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(cb_reader, g_reader);
|
||||
|
||||
/* Deleting the writer must trigger DATA_AVAILABLE as well */
|
||||
cb_called = 0;
|
||||
cb_reader = 0;
|
||||
ret = dds_delete (g_writer);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
g_writer = 0;
|
||||
triggered = waitfor_cb(DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(triggered & DDS_DATA_AVAILABLE_STATUS, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(cb_reader, g_reader);
|
||||
|
||||
/* The listener should have swallowed the status. */
|
||||
ret = dds_read_status(g_subscriber, &status, DDS_DATA_ON_READERS_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
ret = dds_read_status(g_reader, &status, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
}
|
||||
|
||||
CU_Test(ddsc_listener, data_available_delete_writer_disposed, .init=init_triggering_test, .fini=fini_triggering_test)
|
||||
{
|
||||
dds_return_t ret;
|
||||
uint32_t triggered;
|
||||
uint32_t status;
|
||||
RoundTripModule_DataType sample;
|
||||
memset (&sample, 0, sizeof (sample));
|
||||
|
||||
/* We are interested in data available notifications. */
|
||||
dds_lset_data_available(g_listener, data_available_cb);
|
||||
ret = dds_set_listener(g_reader, g_listener);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
|
||||
/* Write & dispose sample and take it so that the instance is empty & disposed. Then deleting
|
||||
the writer should silently drop the instance. */
|
||||
ret = dds_write(g_writer, &sample);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
ret = dds_dispose(g_writer, &sample);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
triggered = waitfor_cb(DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(triggered & DDS_DATA_AVAILABLE_STATUS, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(cb_reader, g_reader);
|
||||
|
||||
/* Take all data so that the instance becomes empty & disposed */
|
||||
do {
|
||||
void *sampleptr = &sample;
|
||||
dds_sample_info_t info;
|
||||
ret = dds_take (g_reader, &sampleptr, &info, 1, 1);
|
||||
} while (ret > 0);
|
||||
|
||||
/* Deleting the writer should not trigger DATA_AVAILABLE with all instances empty & disposed */
|
||||
cb_called = 0;
|
||||
cb_reader = 0;
|
||||
ret = dds_delete (g_writer);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
g_writer = 0;
|
||||
triggered = waitfor_cb(DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(triggered & DDS_DATA_AVAILABLE_STATUS, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(cb_reader, g_reader);
|
||||
|
||||
/* The listener should have swallowed the status. */
|
||||
ret = dds_read_status(g_subscriber, &status, DDS_DATA_ON_READERS_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
ret = dds_read_status(g_reader, &status, DDS_DATA_AVAILABLE_STATUS);
|
||||
CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
|
||||
CU_ASSERT_EQUAL_FATAL(status, 0);
|
||||
}
|
||||
|
||||
CU_Test(ddsc_listener, data_on_readers, .init=init_triggering_test, .fini=fini_triggering_test)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue