From edd5b3038742d6e57c59e0102b89b981e6ec1c2a Mon Sep 17 00:00:00 2001 From: Sean Bright Date: Wed, 13 Sep 2017 15:14:25 -0400 Subject: res_calendar: On reload, update all configuration This changes the behavior of res_calendar to drop all existing calendars and re-create them whenever a reload is done. The Calendar API provides no way for configuration information to be pushed down to calendar 'techs' so updated settings would not take affect until a module unload/load was done or Asterisk was restarted. Asterisk 15+ already has a configuration option 'fetch_again_at_reload' that performs a similar function. Also fix a tiny memory leak in res_calendar_caldav while we're at it. ASTERISK-25524 #close Reported by: Jesper Change-Id: Ib0f8057642e9d471960f1a79fd42e5a3ce587d3b --- include/asterisk/calendar.h | 2 +- res/res_calendar.c | 82 +++++++++++++++------------------------------ res/res_calendar_caldav.c | 1 + 3 files changed, 29 insertions(+), 56 deletions(-) diff --git a/include/asterisk/calendar.h b/include/asterisk/calendar.h index da4af01ef..57140bae2 100644 --- a/include/asterisk/calendar.h +++ b/include/asterisk/calendar.h @@ -133,7 +133,7 @@ struct ast_calendar { pthread_t thread; /*!< The thread that the calendar is loaded/updated in */ ast_cond_t unload; int unloading:1; - int pending_deletion:1; + int pending_deletion:1; /*!< No longer used */ struct ao2_container *events; /*!< The events that are known at this time */ }; diff --git a/res/res_calendar.c b/res/res_calendar.c index 5213d055d..089fb9849 100644 --- a/res/res_calendar.c +++ b/res/res_calendar.c @@ -341,10 +341,7 @@ static void calendar_destructor(void *obj) } ast_calendar_clear_events(cal); ast_string_field_free_memory(cal); - if (cal->vars) { - ast_variables_destroy(cal->vars); - cal->vars = NULL; - } + ast_variables_destroy(cal->vars); ao2_ref(cal->events, -1); ao2_unlock(cal); } @@ -406,28 +403,22 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c { struct ast_calendar *cal; struct ast_variable *v, *last = NULL; - int new_calendar = 0; - if (!(cal = find_calendar(cat))) { - new_calendar = 1; - if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) { - ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n"); - return NULL; - } + if (!(cal = ao2_alloc(sizeof(*cal), calendar_destructor))) { + ast_log(LOG_ERROR, "Could not allocate calendar structure. Stopping.\n"); + return NULL; + } - if (!(cal->events = ao2_container_alloc(CALENDAR_BUCKETS, event_hash_fn, event_cmp_fn))) { - ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat); - cal = unref_calendar(cal); - return NULL; - } + if (!(cal->events = ao2_container_alloc(CALENDAR_BUCKETS, event_hash_fn, event_cmp_fn))) { + ast_log(LOG_ERROR, "Could not allocate events container for %s\n", cat); + cal = unref_calendar(cal); + return NULL; + } - if (ast_string_field_init(cal, 32)) { - ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat); - cal = unref_calendar(cal); - return NULL; - } - } else { - cal->pending_deletion = 0; + if (ast_string_field_init(cal, 32)) { + ast_log(LOG_ERROR, "Couldn't create string fields for %s\n", cat); + cal = unref_calendar(cal); + return NULL; } ast_string_field_set(cal, name, cat); @@ -489,17 +480,15 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c cal->name); } - if (new_calendar) { - cal->thread = AST_PTHREADT_NULL; - ast_cond_init(&cal->unload, NULL); - ao2_link(calendars, cal); - if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) { - /* If we start failing to create threads, go ahead and return NULL - * and the tech module will be unregistered - */ - ao2_unlink(calendars, cal); - cal = unref_calendar(cal); - } + cal->thread = AST_PTHREADT_NULL; + ast_cond_init(&cal->unload, NULL); + ao2_link(calendars, cal); + if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) { + /* If we start failing to create threads, go ahead and return NULL + * and the tech module will be unregistered + */ + ao2_unlink(calendars, cal); + cal = unref_calendar(cal); } return cal; @@ -1770,30 +1759,16 @@ static struct ast_custom_function calendar_event_function = { .read = calendar_event_read, }; -static int cb_pending_deletion(void *user_data, void *arg, int flags) -{ - struct ast_calendar *cal = user_data; - - cal->pending_deletion = 1; - - return CMP_MATCH; -} - -static int cb_rm_pending_deletion(void *user_data, void *arg, int flags) -{ - struct ast_calendar *cal = user_data; - - return cal->pending_deletion ? CMP_MATCH : 0; -} - static int reload(void) { struct ast_calendar_tech *iter; ast_mutex_lock(&reloadlock); - /* Mark existing calendars for deletion */ - ao2_callback(calendars, OBJ_NODATA | OBJ_MULTIPLE, cb_pending_deletion, NULL); + /* Delete all of the calendars */ + ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL); + + /* Load configuration */ load_config(1); AST_LIST_LOCK(&techs); @@ -1804,9 +1779,6 @@ static int reload(void) } AST_LIST_UNLOCK(&techs); - /* Delete calendars that no longer show up in the config */ - ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, cb_rm_pending_deletion, NULL); - ast_mutex_unlock(&reloadlock); return 0; diff --git a/res/res_calendar_caldav.c b/res/res_calendar_caldav.c index 1a4b52bff..9b7679419 100644 --- a/res/res_calendar_caldav.c +++ b/res/res_calendar_caldav.c @@ -80,6 +80,7 @@ static void caldav_destructor(void *obj) if (pvt->session) { ne_session_destroy(pvt->session); } + ne_uri_free(&pvt->uri); ast_string_field_free_memory(pvt); ao2_callback(pvt->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL); -- cgit v1.2.3