From 5d98d226145369e053af306a5c3f3584f78fbe0f Mon Sep 17 00:00:00 2001 From: Paul Thompson Date: Fri, 2 Mar 2018 10:58:53 -0800 Subject: [PATCH 1/4] Remove windup behavior from break_dispatch --- events/equeue/equeue.c | 12 ++++++------ events/equeue/equeue.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/events/equeue/equeue.c b/events/equeue/equeue.c index 436b45c3eb..6b50db439b 100644 --- a/events/equeue/equeue.c +++ b/events/equeue/equeue.c @@ -73,7 +73,7 @@ int equeue_create_inplace(equeue_t *q, size_t size, void *buffer) { q->queue = 0; q->tick = equeue_tick(); q->generation = 0; - q->breaks = 0; + q->break_requested = false; q->background.active = false; q->background.update = 0; @@ -366,7 +366,7 @@ void equeue_cancel(equeue_t *q, int id) { void equeue_break(equeue_t *q) { equeue_mutex_lock(&q->queuelock); - q->breaks++; + q->break_requested = true; equeue_mutex_unlock(&q->queuelock); equeue_sema_signal(&q->eventsema); } @@ -436,10 +436,10 @@ void equeue_dispatch(equeue_t *q, int ms) { equeue_sema_wait(&q->eventsema, deadline); // check if we were notified to break out of dispatch - if (q->breaks) { + if (q->break_requested) { equeue_mutex_lock(&q->queuelock); - if (q->breaks > 0) { - q->breaks--; + if (q->break_requested) { + q->break_requested = false; equeue_mutex_unlock(&q->queuelock); return; } @@ -469,7 +469,7 @@ void equeue_event_dtor(void *p, void (*dtor)(void *)) { } -// simple callbacks +// simple callbacks struct ecallback { void (*cb)(void*); void *data; diff --git a/events/equeue/equeue.h b/events/equeue/equeue.h index 80ee9c7028..4939d7e12f 100644 --- a/events/equeue/equeue.h +++ b/events/equeue/equeue.h @@ -58,7 +58,7 @@ struct equeue_event { typedef struct equeue { struct equeue_event *queue; unsigned tick; - unsigned breaks; + bool break_requested; uint8_t generation; unsigned char *buffer; From 31f581c42572612b76d1cd6c8b9b793a5dcc5f65 Mon Sep 17 00:00:00 2001 From: Paul Thompson Date: Fri, 2 Mar 2018 11:06:15 -0800 Subject: [PATCH 2/4] Clear the break requested flag if the dispatch loop is being broken due to a timeout condition --- events/equeue/equeue.c | 1 + events/equeue/tests/tests.c | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/events/equeue/equeue.c b/events/equeue/equeue.c index 6b50db439b..36e14fdd3a 100644 --- a/events/equeue/equeue.c +++ b/events/equeue/equeue.c @@ -418,6 +418,7 @@ void equeue_dispatch(equeue_t *q, int ms) { q->background.active = true; equeue_mutex_unlock(&q->queuelock); } + q->break_requested = false; return; } } diff --git a/events/equeue/tests/tests.c b/events/equeue/tests/tests.c index 57212de22d..47d5464864 100644 --- a/events/equeue/tests/tests.c +++ b/events/equeue/tests/tests.c @@ -687,6 +687,45 @@ void multithreaded_barrage_test(int N) { equeue_destroy(&q); } +struct sCaQ +{ + int p; + equeue_t* q; +}; + +typedef struct sCaQ CountAndQueue; + +void simple_breaker(void *p) { + CountAndQueue* caq = (CountAndQueue*)p; + equeue_break(caq->q); + usleep(10000); + caq->p++; +} + +void break_request_cleared_on_timeout(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + CountAndQueue pq; + pq.p = 0; + pq.q = &q; + + int id = equeue_call_every(&q, 10, simple_breaker, &pq); + + equeue_dispatch(&q, 10); + test_assert(pq.p == 1); + + equeue_cancel(&q, id); + + int count = 0; + equeue_call_every(&q, 10, simple_func, &count); + + equeue_dispatch(&q, 55); + test_assert(count > 1); + + equeue_destroy(&q); +} int main() { printf("beginning tests...\n"); @@ -712,6 +751,7 @@ int main() { test_run(simple_barrage_test, 20); test_run(fragmenting_barrage_test, 20); test_run(multithreaded_barrage_test, 20); + test_run(break_request_cleared_on_timeout); printf("done!\n"); return test_failure; From bb0d54023f65bba1b0a2403c656e255a26909d46 Mon Sep 17 00:00:00 2001 From: Paul Thompson Date: Fri, 2 Mar 2018 12:44:13 -0800 Subject: [PATCH 3/4] Add test to cover break_dispatch windup --- events/equeue/tests/tests.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/events/equeue/tests/tests.c b/events/equeue/tests/tests.c index 47d5464864..a94ead3b2d 100644 --- a/events/equeue/tests/tests.c +++ b/events/equeue/tests/tests.c @@ -391,6 +391,26 @@ void break_test(void) { equeue_destroy(&q); } +void break_no_windup_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int count = 0; + equeue_call_every(&q, 0, simple_func, &count); + + equeue_break(&q); + equeue_break(&q); + equeue_dispatch(&q, -1); + test_assert(count == 1); + + count = 0; + equeue_dispatch(&q, 55); + test_assert(count > 1); + + equeue_destroy(&q); +} + void period_test(void) { equeue_t q; int err = equeue_create(&q, 2048); @@ -741,6 +761,7 @@ int main() { test_run(cancel_unnecessarily_test); test_run(loop_protect_test); test_run(break_test); + test_run(break_no_windup_test); test_run(period_test); test_run(nested_test); test_run(sloth_test); From dc430ef2d016b41579c1c023deb65302636e5216 Mon Sep 17 00:00:00 2001 From: Paul Thompson Date: Fri, 2 Mar 2018 13:10:27 -0800 Subject: [PATCH 4/4] style fixups --- events/equeue/tests/tests.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/events/equeue/tests/tests.c b/events/equeue/tests/tests.c index a94ead3b2d..00758ec88f 100644 --- a/events/equeue/tests/tests.c +++ b/events/equeue/tests/tests.c @@ -707,17 +707,15 @@ void multithreaded_barrage_test(int N) { equeue_destroy(&q); } -struct sCaQ +struct count_and_queue { int p; equeue_t* q; }; -typedef struct sCaQ CountAndQueue; - void simple_breaker(void *p) { - CountAndQueue* caq = (CountAndQueue*)p; - equeue_break(caq->q); + struct count_and_queue* caq = (struct count_and_queue*)p; + equeue_break(caq->q); usleep(10000); caq->p++; } @@ -727,7 +725,7 @@ void break_request_cleared_on_timeout(void) { int err = equeue_create(&q, 2048); test_assert(!err); - CountAndQueue pq; + struct count_and_queue pq; pq.p = 0; pq.q = &q;