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
This commit is contained in:
Sean Bright
2017-09-13 15:14:25 -04:00
parent 14109355f3
commit 5075cc8eed
3 changed files with 29 additions and 56 deletions

View File

@@ -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 */
};

View File

@@ -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;
}
ao2_ref(cal->events, -1);
ao2_unlock(cal);
}
@@ -406,10 +403,7 @@ 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;
@@ -426,9 +420,6 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c
cal = unref_calendar(cal);
return NULL;
}
} else {
cal->pending_deletion = 0;
}
ast_string_field_set(cal, name, cat);
cal->tech = tech;
@@ -489,7 +480,6 @@ 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);
@@ -500,7 +490,6 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c
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;

View File

@@ -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);