]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/generic/queue: fix a bug
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 10 Aug 2020 12:26:59 +0000 (14:26 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 27 Aug 2020 08:07:30 +0000 (10:07 +0200)
Emptying the queue and using it again... didn't work :-(
Fortunately, no use case in kresd so far could trigger this, I believe:
 - struct session::waiting is a list of tasks waiting
   while connection is being established
 - the temporary queue in session_tasklist_finalize_expired() is also
   only once filled and emptied

lib/generic/queue.h
lib/generic/test_queue.c

index 10cac8973bea682c1c51ffad0fb575cce33da9b2..e538b81afe79266f76ec279bf6e376ce47f641f8 100644 (file)
@@ -198,6 +198,13 @@ static inline void queue_pop_impl(struct queue *q)
        assert(h && h->end > h->begin);
        if (h->end - h->begin == 1) {
                /* removing the last element in the chunk */
+               assert((q->len == 1) == (q->head == q->tail));
+               if (q->len == 1) {
+                       q->tail = NULL;
+                       assert(!h->next);
+               } else {
+                       assert(h->next);
+               }
                q->head = h->next;
                free(h);
        } else {
index 30300a832a3a4d8dffeddc6b6bf646e37c361a42..3a6b5be96e7bb02bcd1d60cecb589761dfe5cfee 100644 (file)
@@ -14,6 +14,12 @@ static void test_int(void **state_)
        queue_int_t q;
        queue_init(q);
 
+       /* Case of emptying the queue (and using again) has been broken for a long time. */
+       queue_push(q, 2);
+       queue_pop(q);
+       queue_push(q, 4);
+       queue_pop(q);
+
        queue_push_head(q, 2);
        queue_push_head(q, 1);
        queue_push_head(q, 0);