From: Jan Hák Date: Tue, 28 May 2019 11:28:57 +0000 (+0200) Subject: events: add blocking scheduling X-Git-Tag: v2.9.0~257^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63f4e20940f4d72e85daecb33749ea479e83eecd;p=thirdparty%2Fknot-dns.git events: add blocking scheduling --- diff --git a/src/knot/events/events.c b/src/knot/events/events.c index 83c61a906b..573812ab2d 100644 --- a/src/knot/events/events.c +++ b/src/knot/events/events.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "libknot/libknot.h" @@ -211,6 +212,7 @@ static void event_wrap(task_t *task) pthread_mutex_unlock(&events->mx); return; } + events->type = type; event_set_time(events, type, 0); events->forced[type] = false; pthread_mutex_unlock(&events->mx); @@ -235,6 +237,7 @@ static void event_wrap(task_t *task) pthread_mutex_lock(&events->mx); events->running = false; + events->type = ZONE_EVENT_INVALID; pthread_mutex_unlock(&events->mx); reschedule(events); } @@ -358,6 +361,27 @@ void zone_events_schedule_user(zone_t *zone, zone_event_type_t type) reschedule(events); } +void zone_events_schedule_blocking(zone_t *zone, zone_event_type_t type, bool user) +{ + if (!zone || !valid_event(type)) { + return; + } + + if (user) { + zone_events_schedule_user(zone, type); + } else { + zone_events_schedule_now(zone, type); + } + + time_t now = time(NULL); + time_t sched_time = zone_events_get_time(zone, type); + while ((zone->events.running && zone->events.type == type) || + (sched_time > 0 && sched_time <= now)) { + usleep(20000); + sched_time = zone_events_get_time(zone, type); + } +} + void zone_events_enqueue(zone_t *zone, zone_event_type_t type) { if (!zone || !valid_event(type)) { @@ -372,6 +396,7 @@ void zone_events_enqueue(zone_t *zone, zone_event_type_t type) if (!events->running && !events->frozen && (!events->ufrozen || !ufreeze_applies(type))) { events->running = true; + events->type = type; event_set_time(events, type, ZONE_EVENT_IMMEDIATE); worker_pool_assign(events->pool, &events->task); pthread_mutex_unlock(&events->mx); diff --git a/src/knot/events/events.h b/src/knot/events/events.h index b5d54f2ca1..5d797ac580 100644 --- a/src/knot/events/events.h +++ b/src/knot/events/events.h @@ -48,7 +48,10 @@ typedef enum zone_event_type { typedef struct zone_events { pthread_mutex_t mx; //!< Mutex protecting the struct. pthread_mutex_t reschedule_lock;//!< Prevent concurrent reschedule() making mess. + + zone_event_type_t type; //!< Type of running event. bool running; //!< Some zone event is being run. + bool frozen; //!< Terminated, don't schedule new events. bool ufrozen; //!< Updates to the zone temporarily frozen by user. @@ -134,6 +137,16 @@ void _zone_events_schedule_at(struct zone *zone, ...); */ void zone_events_schedule_user(struct zone *zone, zone_event_type_t type); +/*! + * \brief Schedule new zone event as soon as possible and wait for it's + * completion (end of task run), with optional forced flag. + * + * \param zone Zone to schedule new event for. + * \param type Zone event type. + * \param user Forced flag indication. + */ +void zone_events_schedule_blocking(struct zone *zone, zone_event_type_t type, bool user); + /*! * \brief Freeze all zone events and prevent new events from running. *