From 104efd92c5474245cbcb192fd3bd130af724e50c Mon Sep 17 00:00:00 2001 From: Marek Vavrusa <marek.vavrusa@nic.cz> Date: Thu, 5 Dec 2013 16:37:57 +0100 Subject: [PATCH] evsched now cancells even self-scheduling events * evsched now uses common errcodes instead of magic values * updated tests --- src/common/evsched.c | 69 +++++++++++++++++++++-------------------- src/common/evsched.h | 33 +++++--------------- src/knot/server/zones.c | 2 +- tests/events.c | 3 +- 4 files changed, 46 insertions(+), 61 deletions(-) diff --git a/src/common/evsched.c b/src/common/evsched.c index be8e621a59..6fa0fa8c6f 100644 --- a/src/common/evsched.c +++ b/src/common/evsched.c @@ -19,6 +19,7 @@ #include <stdlib.h> #include <stdio.h> +#include "common/errcode.h" #include "common/evsched.h" /*! \todo Fix properly (issue #1581). */ @@ -64,13 +65,13 @@ static void evsched_settimer(event_t *e, uint32_t dt) } /*! \brief Singleton application-wide event scheduler. */ -evsched_t *s_evsched = 0; +evsched_t *s_evsched = NULL; evsched_t *evsched_new() { evsched_t *s = malloc(sizeof(evsched_t)); if (!s) { - return 0; + return NULL; } memset(s, 0, sizeof(evsched_t)); @@ -88,10 +89,7 @@ evsched_t *evsched_new() void evsched_delete(evsched_t **s) { - if (!s) { - return; - } - if (!*s) { + if (s == NULL || *s == NULL) { return; } @@ -119,13 +117,13 @@ void evsched_delete(evsched_t **s) /* Free scheduler. */ free(*s); - *s = 0; + *s = NULL; } event_t *evsched_event_new(evsched_t *s, int type) { if (!s) { - return 0; + return NULL; } /* Allocate. */ @@ -165,7 +163,7 @@ event_t* evsched_next(evsched_t *s) { /* Check. */ if (!s) { - return 0; + return NULL; } /* Lock calendar. */ @@ -214,31 +212,31 @@ event_t* evsched_next(evsched_t *s) /* Unlock calendar, this shouldn't happen. */ pthread_mutex_unlock(&s->mx); - return 0; + return NULL; } int evsched_event_finished(evsched_t *s) { if (!s) { - return -1; + return KNOT_EINVAL; } /* Mark as finished. */ if (s->cur) { s->cur = NULL; pthread_mutex_unlock(&s->rl); - return 0; + return KNOT_EOK; } - /* Finished event is not current. */ - return -1; + /* No event running. */ + return KNOT_ENOTRUNNING; } int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt) { if (!s || !ev) { - return -1; + return KNOT_EINVAL; } /* Update event timer. */ @@ -254,19 +252,19 @@ int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt) pthread_cond_broadcast(&s->notify); pthread_mutex_unlock(&s->mx); - return 0; + return KNOT_EOK; } event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t dt) { if (!s) { - return 0; + return NULL; } /* Create event. */ event_t *e = evsched_event_new(s, EVSCHED_CB); if (!e) { - return 0; + return NULL; } e->cb = cb; e->data = data; @@ -274,7 +272,7 @@ event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t d /* Schedule. */ if (evsched_schedule(s, e, dt) != 0) { evsched_event_free(s, e); - e = 0; + e = NULL; } return e; @@ -283,30 +281,30 @@ event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t d event_t* evsched_schedule_term(evsched_t *s, uint32_t dt) { if (!s) { - return 0; + return NULL; } /* Create event. */ event_t *e = evsched_event_new(s, EVSCHED_TERM); if (!e) { - return 0; + return NULL; } /* Schedule. */ if (evsched_schedule(s, e, dt) != 0) { evsched_event_free(s, e); - e = 0; + e = NULL; } return e; } -int evsched_cancel(evsched_t *s, event_t *ev) +static int evsched_try_cancel(evsched_t *s, event_t *ev) { - int found; + int found = 0; if (!s || !ev) { - return -1; + return KNOT_EINVAL; } /* Make sure not running. */ @@ -325,7 +323,7 @@ int evsched_cancel(evsched_t *s, event_t *ev) */ if (s->cur == ev) { s->cur = NULL; /* Invalidate */ - found = -1; /* Return error, since the event is running again */ + found = KNOT_EAGAIN; /* Already ran, try again. */ } /* Unlock calendar. */ @@ -334,20 +332,25 @@ int evsched_cancel(evsched_t *s, event_t *ev) /* Enable running events. */ pthread_mutex_unlock(&s->rl); + if (found) { + return KNOT_EOK; + } - return found; + return KNOT_ENOENT; } -int evsched_cancel_child(evsched_t *s, event_t *ev) +int evsched_cancel(evsched_t *s, event_t *ev) { if (!s || !ev) { - return -1; + return KNOT_EINVAL; } - int ret = 0; - while (((ret = evsched_cancel(s, ev)) < 0) && s && ev) { - ; + /* Event may have already run, try again. */ + int ret = KNOT_EAGAIN; + while (ret == KNOT_EAGAIN) { + ret = evsched_try_cancel(s, ev); } - return ret; + /* Now we're sure event is cancelled or finished. */ + return KNOT_EOK; } diff --git a/src/common/evsched.h b/src/common/evsched.h index be0297aead..4e710a59b8 100644 --- a/src/common/evsched.h +++ b/src/common/evsched.h @@ -155,8 +155,9 @@ event_t* evsched_next(evsched_t *s); * * \param s Event scheduler. * - * \retval 0 if successful. - * \retval -1 on errors. + * \retval KNOT_EOK if successful. + * \retval KNOT_EINVAL + * \retval KNOT_ENOTRUNNING */ int evsched_event_finished(evsched_t *s); @@ -167,8 +168,8 @@ int evsched_event_finished(evsched_t *s); * \param ev Prepared event. * \param dt Time difference in milliseconds from now (dt is relative). * - * \retval 0 on success. - * \retval <0 on error. + * \retval KNOT_EOK on success. + * \retval KNOT_EINVAL */ int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt); @@ -212,31 +213,11 @@ event_t* evsched_schedule_term(evsched_t *s, uint32_t dt); * \param s Event scheduler. * \param ev Scheduled event. * - * \retval 0 if already ran. - * \retval 1 if found and cancelled. - * \retval <0 on error. + * \retval KNOT_EOK + * \retval KNOT_EINVAL */ int evsched_cancel(evsched_t *s, event_t *ev); -/*! - * \brief Cancel a scheduled event. Same as 'evsched_cancel' but also cancels - * event that might have been scheduled by the cancelled event. - * - * \warning May block until current running event is finished (as it cannot - * interrupt running event). - * - * \warning Never cancel event in it's callback. As it never finishes, - * it deadlocks. - * - * \param s Event scheduler. - * \param ev Scheduled event. - * - * \retval 0 if already ran. - * \retval 1 if found and cancelled. - * \retval <0 on error. - */ -int evsched_cancel_child(evsched_t *s, event_t *ev); - /* Singleton event scheduler pointer. */ extern evsched_t *s_evsched; diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 90a799d76f..f95cdab070 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -2613,7 +2613,7 @@ int zones_cancel_dnssec(knot_zone_t *zone) evsched_t *scheduler = zd->server->sched; if (zd->dnssec_timer) { - evsched_cancel_child(scheduler, zd->dnssec_timer); + evsched_cancel(scheduler, zd->dnssec_timer); } return KNOT_EOK; diff --git a/tests/events.c b/tests/events.c index 664409d302..2ba8177c19 100644 --- a/tests/events.c +++ b/tests/events.c @@ -22,6 +22,7 @@ #include "common/evqueue.h" #include "common/evsched.h" +#include "common/errcode.h" void* term_thr(void *arg) { @@ -146,7 +147,7 @@ int main(int argc, char *argv[]) // 7. Insert and immediately cancel an event e = evsched_schedule_cb(s, 0, (void*)0xdead, 1000); ret = evsched_cancel(s, e); - ok(ret >= 0, "evsched: inserted and cancelled an event"); + ok(ret == KNOT_EOK, "evsched: inserted and cancelled an event"); if (e) { evsched_event_free(s, e); } -- GitLab