diff --git a/events/include/events/equeue.h b/events/include/events/equeue.h index e488de2af2..15fcf860c3 100644 --- a/events/include/events/equeue.h +++ b/events/include/events/equeue.h @@ -61,8 +61,9 @@ struct equeue_event { typedef struct equeue { struct equeue_event *queue; unsigned tick; + + uint16_t generation; bool break_requested; - uint8_t generation; unsigned char *buffer; unsigned npw2; diff --git a/events/source/equeue.c b/events/source/equeue.c index 8126b23418..7c77c7b9c2 100644 --- a/events/source/equeue.c +++ b/events/source/equeue.c @@ -351,8 +351,8 @@ static struct equeue_event *equeue_dequeue(equeue_t *q, unsigned target) { equeue_mutex_lock(&q->queuelock); - // find all expired events and mark a new generation - q->generation += 1; + // find all expired events + if (equeue_tickdiff(q->tick, target) <= 0) { q->tick = target; } @@ -370,6 +370,12 @@ static struct equeue_event *equeue_dequeue(equeue_t *q, unsigned target) *p = 0; + /* we only increment the generation if events have been taken off the queue + * as this is the only time cancellation may conflict with dequeueing */ + if (head) { + q->generation += 1; + } + equeue_mutex_unlock(&q->queuelock); // reverse and flatten each slot to match insertion order