diff --git a/master/master.c b/master/master.c index 1f20fc9d..611cb45e 100644 --- a/master/master.c +++ b/master/master.c @@ -841,6 +841,8 @@ void ec_master_queue_datagram( ec_datagram_t *datagram /**< datagram */ ) { + ec_datagram_t *queued_datagram; + switch (datagram->state) { case EC_DATAGRAM_QUEUED: datagram->skip_count++; @@ -855,12 +857,28 @@ void ec_master_queue_datagram( break; default: - list_add_tail(&datagram->queue, &master->datagram_queue); - datagram->state = EC_DATAGRAM_QUEUED; break; } -} + /* It is possible, that a datagram in the queue is re-initialized with the + * ec_datagram_() methods and then shall be queued with this method. + * In that case, the state is already reset to EC_DATAGRAM_INIT. Check if + * the datagram is queued to avoid duplicate queuing (which results in an + * infinite loop!). Set the state to EC_DATAGRAM_QUEUED again, probably + * causing an unmatched datagram. */ + list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { + if (queued_datagram == datagram) { + datagram->skip_count++; + EC_MASTER_DBG(master, 1, "Skipping re-initialized datagram %p.\n", + datagram); + datagram->state = EC_DATAGRAM_QUEUED; + return; + } + } + + list_add_tail(&datagram->queue, &master->datagram_queue); + datagram->state = EC_DATAGRAM_QUEUED; +} /*****************************************************************************/