Skip to content

Commit

Permalink
Fixed uncalled destructors in equeue_destroy
Browse files Browse the repository at this point in the history
Before, only the heads of slots were correctly destructed.

Fixed and added test case.
  • Loading branch information
geky committed Aug 3, 2016
1 parent eb6eee1 commit be5ffc1
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 23 deletions.
11 changes: 7 additions & 4 deletions equeue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
62 changes: 43 additions & 19 deletions tests/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);

Expand All @@ -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) {
Expand Down

0 comments on commit be5ffc1

Please sign in to comment.