diff --git a/src/data.c b/src/data.c index 59b491b..b222a15 100644 --- a/src/data.c +++ b/src/data.c @@ -1162,13 +1162,21 @@ lmap_event_valid(struct lmap *lmap, struct event *event) valid = 0; } - if (event->type == LMAP_EVENT_TYPE_PERIODIC - && ! (event->flags & LMAP_EVENT_FLAG_INTERVAL_SET)) { - lmap_err("event %s%s%srequires an interval", - event->name ? "'" : "", - event->name ? event->name : "", - event->name ? "' " : ""); - valid = 0; + if (event->type == LMAP_EVENT_TYPE_PERIODIC) { + if (!(event->flags & LMAP_EVENT_FLAG_INTERVAL_SET)) { + lmap_err("event %s%s%srequires an interval", + event->name ? "'" : "", + event->name ? event->name : "", + event->name ? "' " : ""); + valid = 0; + } else if (event->flags & LMAP_EVENT_FLAG_RANDOM_SPREAD_SET + && event->random_spread >= event->interval) { + lmap_err("event %s%s%shas a random spread too large for its interval", + event->name ? "'" : "", + event->name ? event->name : "", + event->name ? "' " : ""); + valid = 0; + } } if (event->type == LMAP_EVENT_TYPE_CALENDAR) { if (event->months == 0) { diff --git a/src/runner.c b/src/runner.c index f19338e..19d6bcc 100644 --- a/src/runner.c +++ b/src/runner.c @@ -43,15 +43,28 @@ static void event_gaga(struct event *event, struct event **ev, short what, event_callback_fn func, struct timeval *tv) { - assert(event && event->lmapd && ev && *ev == NULL); + assert(event && event->lmapd && ev); - *ev = event_new(event->lmapd->base, -1, what, func, event); - if (!*ev || event_add(*ev, tv) < 0) { - lmap_err("failed to create/add event for '%s'", event->name); + if (!(*ev)) { + *ev = event_new(event->lmapd->base, -1, what, func, event); + if (!*ev || event_add(*ev, tv) < 0) { + lmap_err("failed to create/add event for '%s'", event->name); + } + } else { + lmap_err("failed to create/add event for '%s': event already pending, maybe due to too large a random spread?", event->name); } } #endif +static void +safe_event_free(struct event * event) +{ + if (event) + event_free(event); + else + lmap_wrn("internal error: tried to free an event twice"); +} + /** * @brief Generate a uniformly distributed random number. * @@ -787,7 +800,7 @@ fire_cb(evutil_socket_t fd, short events, void *context) suppress_cb(event->lmapd, event); execute_cb(event->lmapd, event); - event_free(event->fire_event); + safe_event_free(event->fire_event); event->fire_event = NULL; } @@ -808,7 +821,7 @@ trigger_periodic_cb(evutil_socket_t fd, short events, void *context) if (t.tv_sec > event->end) { /* XXX disable related schedules / suppressions */ lmap_wrn("event '%s' ending", event->name); - event_free(event->trigger_event); + safe_event_free(event->trigger_event); event->trigger_event = NULL; return; } @@ -836,7 +849,7 @@ trigger_calendar_cb(evutil_socket_t fd, short events, void *context) if (t.tv_sec > event->end) { /* XXX disable related schedules / suppressions */ lmap_wrn("event '%s' ending", event->name); - event_free(event->trigger_event); + safe_event_free(event->trigger_event); event->trigger_event = NULL; return; } @@ -845,7 +858,7 @@ trigger_calendar_cb(evutil_socket_t fd, short events, void *context) match = lmap_event_calendar_match(event, &t.tv_sec); if (match < 0) { lmap_err("shutting down '%s'", event->name); - event_free(event->trigger_event); + safe_event_free(event->trigger_event); event->trigger_event = NULL; return; } @@ -885,7 +898,7 @@ startup_cb(evutil_socket_t fd, short events, void *context) break; } - event_free(event->start_event); + safe_event_free(event->start_event); event->start_event = NULL; }