diff -r 42fbd117c3e3 -r eefccfa312ef master/master.c --- a/master/master.c Fri Jul 08 15:31:46 2011 +0200 +++ b/master/master.c Thu Jul 21 18:25:38 2011 +0200 @@ -841,6 +841,8 @@ ec_datagram_t *datagram /**< datagram */ ) { + ec_datagram_t *queued_datagram; + switch (datagram->state) { case EC_DATAGRAM_QUEUED: datagram->skip_count++; @@ -855,12 +857,28 @@ break; default: - list_add_tail(&datagram->queue, &master->datagram_queue); + 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; - break; - } -} - + return; + } + } + + list_add_tail(&datagram->queue, &master->datagram_queue); + datagram->state = EC_DATAGRAM_QUEUED; +} /*****************************************************************************/