lock observer list to avoid a race condition between attach/detach and signalling by a RHC

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2018-07-17 21:36:26 +02:00
parent 24f622b114
commit 520ca47938
2 changed files with 17 additions and 3 deletions

View file

@ -133,6 +133,7 @@ typedef struct dds_entity
os_cond m_cond;
c_listener_t m_listener;
uint32_t m_trigger;
os_mutex m_observers_lock;
dds_entity_observer *m_observers;
struct ut_handlelink *m_hdllink;
}

View file

@ -237,6 +237,7 @@ dds_entity_init(
e->m_status_enable = mask | DDS_INTERNAL_STATUS_MASK;
os_mutexInit (&e->m_mutex);
os_mutexInit (&e->m_observers_lock);
os_condInit (&e->m_cond, &e->m_mutex);
if (parent) {
@ -428,6 +429,7 @@ dds_delete_impl(
dds_qos_delete (e->m_qos);
os_condDestroy (&e->m_cond);
os_mutexDestroy (&e->m_mutex);
os_mutexDestroy (&e->m_observers_lock);
dds_free (e);
}
@ -1104,6 +1106,7 @@ dds_entity_observer_register_nl(
o->m_cb = cb;
o->m_observer = observer;
o->m_next = NULL;
os_mutexLock(&observed->m_observers_lock);
if (observed->m_observers == NULL) {
observed->m_observers = o;
} else {
@ -1122,6 +1125,7 @@ dds_entity_observer_register_nl(
last->m_next = o;
}
}
os_mutexUnlock(&observed->m_observers_lock);
return rc;
}
@ -1155,7 +1159,9 @@ dds_entity_observer_unregister_nl(
{
dds__retcode_t rc = DDS_RETCODE_PRECONDITION_NOT_MET;
dds_entity_observer *prev = NULL;
dds_entity_observer *idx = observed->m_observers;
dds_entity_observer *idx;
os_mutexLock(&observed->m_observers_lock);
idx = observed->m_observers;
while (idx != NULL) {
if (idx->m_observer == observer) {
if (prev == NULL) {
@ -1171,6 +1177,7 @@ dds_entity_observer_unregister_nl(
idx = idx->m_next;
}
}
os_mutexUnlock(&observed->m_observers_lock);
return rc;
}
@ -1201,13 +1208,16 @@ dds_entity_observers_delete(
_In_ dds_entity *observed)
{
dds_entity_observer *next;
dds_entity_observer *idx = observed->m_observers;
dds_entity_observer *idx;
os_mutexLock(&observed->m_observers_lock);
idx = observed->m_observers;
while (idx != NULL) {
next = idx->m_next;
os_free(idx);
idx = next;
}
observed->m_observers = NULL;
os_mutexUnlock(&observed->m_observers_lock);
}
@ -1217,11 +1227,14 @@ dds_entity_observers_signal(
_In_ dds_entity *observed,
_In_ uint32_t status)
{
dds_entity_observer *idx = observed->m_observers;
dds_entity_observer *idx;
os_mutexLock(&observed->m_observers_lock);
idx = observed->m_observers;
while (idx != NULL) {
idx->m_cb(idx->m_observer, observed->m_hdl, status);
idx = idx->m_next;
}
os_mutexUnlock(&observed->m_observers_lock);
}
_Pre_satisfies_(entity & DDS_ENTITY_KIND_MASK)