From be5ffc15f80209d7c5529242cfd5d5a1a8c6d36b Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 2 Aug 2016 23:40:04 -0500 Subject: [PATCH] Fixed uncalled destructors in equeue_destroy Before, only the heads of slots were correctly destructed. Fixed and added test case. --- equeue.c | 11 +++++---- tests/tests.c | 62 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/equeue.c b/equeue.c index 8530e20..0eef0a4 100644 --- a/equeue.c +++ b/equeue.c @@ -57,10 +57,13 @@ int equeue_create_inplace(equeue_t *q, size_t size, void *buffer) { } void equeue_destroy(equeue_t *q) { - while (q->queue) { - struct equeue_event *e = q->queue; - q->queue = e->next; - equeue_dealloc(q, e+1); + // call destructors on pending events + for (struct equeue_event *es = q->queue; es; es = es->next) { + for (struct equeue_event *e = q->queue; e; e = e->sibling) { + if (e->dtor) { + e->dtor(e + 1); + } + } } equeue_mutex_destroy(&q->memlock); diff --git a/tests/tests.c b/tests/tests.c index fc4aed4..9f35c40 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -47,13 +47,13 @@ void simple_func(void *p) { } struct indirect { - bool *touched; + int *touched; uint8_t buffer[7]; }; void indirect_func(void *p) { struct indirect *i = (struct indirect*)p; - *i->touched = true; + (*i->touched)++; } struct timing { @@ -142,7 +142,7 @@ void simple_post_test(void) { int err = equeue_create(&q, 2048); test_assert(!err); - bool touched = false; + int touched = false; struct indirect *i = equeue_alloc(&q, sizeof(struct indirect)); test_assert(i); @@ -162,29 +162,53 @@ void destructor_test(void) { int err = equeue_create(&q, 2048); test_assert(!err); - bool touched = false; - struct indirect *i = equeue_alloc(&q, sizeof(struct indirect)); - test_assert(i); + int touched; + struct indirect *e; + int ids[3]; - i->touched = &touched; - equeue_event_dtor(i, indirect_func); - int id = equeue_post(&q, pass_func, i); - test_assert(id); + touched = 0; + for (int i = 0; i < 3; i++) { + e = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(e); + + e->touched = &touched; + equeue_event_dtor(e, indirect_func); + int id = equeue_post(&q, pass_func, e); + test_assert(id); + } equeue_dispatch(&q, 0); - test_assert(touched); + test_assert(touched == 3); - touched = false; - i = equeue_alloc(&q, sizeof(struct indirect)); - test_assert(i); + touched = 0; + for (int i = 0; i < 3; i++) { + e = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(e); - i->touched = &touched; - equeue_event_dtor(i, indirect_func); - id = equeue_post(&q, pass_func, i); - test_assert(id); + e->touched = &touched; + equeue_event_dtor(e, indirect_func); + ids[i] = equeue_post(&q, pass_func, e); + test_assert(ids[i]); + } + + for (int i = 0; i < 3; i++) { + equeue_cancel(&q, ids[i]); + } + test_assert(touched == 3); + + touched = 0; + for (int i = 0; i < 3; i++) { + e = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(e); + + e->touched = &touched; + equeue_event_dtor(e, indirect_func); + int id = equeue_post(&q, pass_func, e); + test_assert(id); + } equeue_destroy(&q); - test_assert(touched); + test_assert(touched == 3); } void allocation_failure_test(void) {