diff -r 9cd87b98fac6 -r 23ffec5c9c5b master/master.c --- a/master/master.c Fri Jul 08 14:28:07 2011 +0200 +++ b/master/master.c Thu Jul 21 18:25:38 2011 +0200 @@ -1,6 +1,6 @@ /****************************************************************************** * - * $Id: master.c,v b5391b329b5d 2010/11/30 14:24:21 fp $ + * $Id$ * * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH * @@ -821,6 +821,8 @@ ec_datagram_t *datagram /**< datagram */ ) { + ec_datagram_t *queued_datagram; + switch (datagram->state) { case EC_DATAGRAM_QUEUED: datagram->skip_count++; @@ -835,10 +837,27 @@ 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; } /*****************************************************************************/