diff options
Diffstat (limited to 'src/knot/events/events.h')
-rw-r--r-- | src/knot/events/events.h | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/src/knot/events/events.h b/src/knot/events/events.h new file mode 100644 index 0000000..8ede5fb --- /dev/null +++ b/src/knot/events/events.h @@ -0,0 +1,214 @@ +/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <pthread.h> +#include <stdbool.h> +#include <sys/time.h> + +#include "knot/conf/conf.h" +#include "knot/common/evsched.h" +#include "knot/worker/pool.h" +#include "libknot/db/db.h" + +struct zone; + +typedef enum zone_event_type { + ZONE_EVENT_INVALID = -1, + // supported event types + ZONE_EVENT_LOAD = 0, + ZONE_EVENT_REFRESH, + ZONE_EVENT_UPDATE, + ZONE_EVENT_EXPIRE, + ZONE_EVENT_FLUSH, + ZONE_EVENT_BACKUP, + ZONE_EVENT_NOTIFY, + ZONE_EVENT_DNSSEC, + ZONE_EVENT_UFREEZE, + ZONE_EVENT_UTHAW, + ZONE_EVENT_DS_CHECK, + ZONE_EVENT_DS_PUSH, + // terminator + ZONE_EVENT_COUNT, +} zone_event_type_t; + +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. + pthread_cond_t *run_end; //!< Notify this one after finishing a job. + + bool frozen; //!< Terminated, don't schedule new events. + bool ufrozen; //!< Updates to the zone temporarily frozen by user. + + event_t *event; //!< Scheduler event. + worker_pool_t *pool; //!< Server worker pool. + + worker_task_t task; //!< Event execution context. + time_t time[ZONE_EVENT_COUNT]; //!< Event execution times. + bool forced[ZONE_EVENT_COUNT]; //!< Flag that the event was invoked by user ctl. + pthread_cond_t *blocking[ZONE_EVENT_COUNT]; //!< For blocking events: dispatching cond. + int result[ZONE_EVENT_COUNT]; //!< Event return values (in blocking operations). +} zone_events_t; + +/*! + * \brief Initialize zone events. + * + * The function will not set up the scheduling, use \ref zone_events_setup + * to do that. + * + * \param zone Pointer to zone (context of execution). + * + * \return KNOT_E* + */ +int zone_events_init(struct zone *zone); + +/*! + * \brief Set up zone events execution. + * + * \param zone Zone to setup. + * \param workers Worker thread pool. + * \param scheduler Event scheduler. + * + * \return KNOT_E* + */ +int zone_events_setup(struct zone *zone, worker_pool_t *workers, + evsched_t *scheduler); + +/*! + * \brief Deinitialize zone events. + * + * \param zone Zone whose events we want to deinitialize. + */ +void zone_events_deinit(struct zone *zone); + +/*! + * \brief Enqueue event type for asynchronous execution. + * + * \note This is similar to the scheduling an event for NOW, but it can + * bypass the event scheduler if no event is running at the moment. + * + * \param zone Zone to schedule new event for. + * \param type Type of event. + */ +void zone_events_enqueue(struct zone *zone, zone_event_type_t type); + +/*! + * \brief Schedule new zone event. + * + * The function allows to set multiple events at once. + * + * The function interprets time values (t) as follows: + * + * t > 0: schedule timer for a given time + * t = 0: cancel the timer + * t < 0: ignore change in the timer + * + * If the event is already scheduled, the new time will be set only if the + * new time is earlier than the currently scheduled one. To override the + * check, cancel and schedule the event in a single function call. + * + * \param zone Zone to schedule new event for. + * \param ... Sequence of zone_event_type_t and time_t terminated with + * ZONE_EVENT_INVALID. + */ +void _zone_events_schedule_at(struct zone *zone, ...); + +#define zone_events_schedule_at(zone, events...) \ + _zone_events_schedule_at(zone, events, ZONE_EVENT_INVALID) + +#define zone_events_schedule_now(zone, type) \ + zone_events_schedule_at(zone, type, time(NULL)) + +/*! + * \brief Schedule zone event to now, with forced flag. + */ +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. + * + * \return KNOT_E* + */ +int 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. + * + * \param zone Zone to freeze events for. + */ +void zone_events_freeze(struct zone *zone); + +/*! + * \brief Freeze zone events and wait for running event to finish. + * + * \param zone Zone to freeze events for. + */ +void zone_events_freeze_blocking(struct zone *zone); + +/*! + * \brief ufreeze_applies + * \param type Type of event to be checked + * \return true / false if user freeze applies + */ +bool ufreeze_applies(zone_event_type_t type); + +/*! + * \brief Start the events processing. + * + * \param zone Zone to start processing for. + */ +void zone_events_start(struct zone *zone); + +/*! + * \brief Return time of the occurrence of the given event. + * + * \param zone Zone to get event time from. + * \param type Event type. + * + * \retval time of the event when event found + * \retval 0 when the event is not planned + * \retval negative value if event is invalid + */ +time_t zone_events_get_time(const struct zone *zone, zone_event_type_t type); + +/*! + * \brief Return text name of the event. + * + * \param type Type of event. + * + * \retval String with event name if it exists. + * \retval NULL if the event does not exist. + */ +const char *zone_events_get_name(zone_event_type_t type); + +/*! + * \brief Return time and type of the next event. + * + * \param zone Zone to get next event from. + * \param type [out] Type of the next event will be stored in the parameter. + * + * \return time of the next event or an error (negative number) + */ +time_t zone_events_get_next(const struct zone *zone, zone_event_type_t *type); |