diff options
-rw-r--r-- | include/asterisk/calendar.h | 14 | ||||
-rw-r--r-- | res/res_calendar.c | 40 | ||||
-rw-r--r-- | res/res_calendar_caldav.c | 11 | ||||
-rw-r--r-- | res/res_calendar_exchange.c | 11 | ||||
-rw-r--r-- | res/res_calendar_icalendar.c | 11 |
5 files changed, 71 insertions, 16 deletions
diff --git a/include/asterisk/calendar.h b/include/asterisk/calendar.h index dd14f963a..29c67de17 100644 --- a/include/asterisk/calendar.h +++ b/include/asterisk/calendar.h @@ -60,8 +60,6 @@ * to unregister that module's calendar type (usually done in module_unload()) */ -extern struct ast_config *ast_calendar_config; - struct ast_calendar; struct ast_calendar_event; @@ -184,4 +182,16 @@ struct ast_calendar_event *ast_calendar_unref_event(struct ast_calendar_event *e */ void ast_calendar_clear_events(struct ast_calendar *cal); +/*! \brief Grab and lock pointer to the calendar config (read only) + * + * \note ast_calendar_config_release must be called when finished with the pointer + * + * \return the parsed calendar config + */ +const struct ast_config *ast_calendar_config_acquire(void); + +/*! \brief Release the calendar config + */ +void ast_calendar_config_release(void); + #endif /* _ASTERISK_CALENDAR_H */ diff --git a/res/res_calendar.c b/res/res_calendar.c index e916ac0f0..6ec7b424c 100644 --- a/res/res_calendar.c +++ b/res/res_calendar.c @@ -190,7 +190,25 @@ struct evententry { static AST_LIST_HEAD_STATIC(techs, ast_calendar_tech); AST_LIST_HEAD_NOLOCK(eventlist, evententry); /* define the type */ -struct ast_config *ast_calendar_config; +static struct ast_config *calendar_config; +AST_RWLOCK_DEFINE_STATIC(config_lock); + +const struct ast_config *ast_calendar_config_acquire(void) +{ + ast_rwlock_rdlock(&config_lock); + + if (!calendar_config) { + ast_rwlock_unlock(&config_lock); + return NULL; + } + + return calendar_config; +} + +void ast_calendar_config_release(void) +{ + ast_rwlock_unlock(&config_lock); +} static struct ast_calendar *unref_calendar(struct ast_calendar *cal) { @@ -390,29 +408,33 @@ static int load_tech_calendars(struct ast_calendar_tech *tech) const char *cat = NULL; const char *val; - if (!ast_calendar_config) { + if (!calendar_config) { ast_log(LOG_WARNING, "Calendar support disabled, not loading %s calendar module\n", tech->type); return -1; } - while ((cat = ast_category_browse(ast_calendar_config, cat))) { + ast_rwlock_wrlock(&config_lock); + while ((cat = ast_category_browse(calendar_config, cat))) { if (!strcasecmp(cat, "general")) { continue; } - if (!(val = ast_variable_retrieve(ast_calendar_config, cat, "type")) || strcasecmp(val, tech->type)) { + if (!(val = ast_variable_retrieve(calendar_config, cat, "type")) || strcasecmp(val, tech->type)) { continue; } /* A serious error occurred loading calendars from this tech and it should be disabled */ - if (!(cal = build_calendar(ast_calendar_config, cat, tech))) { + if (!(cal = build_calendar(calendar_config, cat, tech))) { ast_calendar_unregister(tech); + ast_rwlock_unlock(&config_lock); return -1; } cal = unref_calendar(cal); } + ast_rwlock_unlock(&config_lock); + return 0; } @@ -862,11 +884,13 @@ static int load_config(void *data) return 0; } - if (ast_calendar_config) { - ast_config_destroy(ast_calendar_config); + ast_rwlock_wrlock(&config_lock); + if (calendar_config) { + ast_config_destroy(calendar_config); } - ast_calendar_config = tmpcfg; + calendar_config = tmpcfg; + ast_rwlock_unlock(&config_lock); return 0; } diff --git a/res/res_calendar_caldav.c b/res/res_calendar_caldav.c index 64f8f2aa1..2b3f5a334 100644 --- a/res/res_calendar_caldav.c +++ b/res/res_calendar_caldav.c @@ -536,11 +536,12 @@ static int verify_cert(void *userdata, int failures, const ne_ssl_certificate *c static void *caldav_load_calendar(void *void_data) { struct caldav_pvt *pvt; + const struct ast_config *cfg; struct ast_variable *v; struct ast_calendar *cal = void_data; ast_mutex_t refreshlock; - if (!(cal && ast_calendar_config)) { + if (!(cal && (cfg = ast_calendar_config_acquire()))) { ast_log(LOG_ERROR, "You must enable calendar support for res_caldav to load\n"); return NULL; } @@ -551,11 +552,13 @@ static void *caldav_load_calendar(void *void_data) } else { ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n"); } + ast_calendar_config_release(); return NULL; } if (!(pvt = ao2_alloc(sizeof(*pvt), caldav_destructor))) { ast_log(LOG_ERROR, "Could not allocate caldav_pvt structure for calendar: %s\n", cal->name); + ast_calendar_config_release(); return NULL; } @@ -565,6 +568,7 @@ static void *caldav_load_calendar(void *void_data) ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name); pvt = unref_caldav(pvt); ao2_unlock(cal); + ast_calendar_config_release(); return NULL; } @@ -572,10 +576,11 @@ static void *caldav_load_calendar(void *void_data) ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name); pvt = unref_caldav(pvt); ao2_unlock(cal); + ast_calendar_config_release(); return NULL; } - for (v = ast_variable_browse(ast_calendar_config, cal->name); v; v = v->next) { + for (v = ast_variable_browse(cfg, cal->name); v; v = v->next) { if (!strcasecmp(v->name, "url")) { ast_string_field_set(pvt, url, v->value); } else if (!strcasecmp(v->name, "user")) { @@ -585,6 +590,8 @@ static void *caldav_load_calendar(void *void_data) } } + ast_calendar_config_release(); + if (ast_strlen_zero(pvt->url)) { ast_log(LOG_WARNING, "No URL was specified for CalDAV calendar '%s' - skipping.\n", cal->name); pvt = unref_caldav(pvt); diff --git a/res/res_calendar_exchange.c b/res/res_calendar_exchange.c index 0b4e661e2..05a42633a 100644 --- a/res/res_calendar_exchange.c +++ b/res/res_calendar_exchange.c @@ -619,11 +619,12 @@ static int update_exchangecal(struct exchangecal_pvt *pvt) static void *exchangecal_load_calendar(void *void_data) { struct exchangecal_pvt *pvt; + const struct ast_config *cfg; struct ast_variable *v; struct ast_calendar *cal = void_data; ast_mutex_t refreshlock; - if (!(cal && ast_calendar_config)) { + if (!(cal && (cfg = ast_calendar_config_acquire()))) { ast_log(LOG_ERROR, "You must enable calendar support for res_exchangecal to load\n"); return NULL; } @@ -634,11 +635,13 @@ static void *exchangecal_load_calendar(void *void_data) } else { ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n"); } + ast_calendar_config_release(); return NULL; } if (!(pvt = ao2_alloc(sizeof(*pvt), exchangecal_destructor))) { ast_log(LOG_ERROR, "Could not allocate exchangecal_pvt structure for calendar: %s\n", cal->name); + ast_calendar_config_release(); return NULL; } @@ -648,6 +651,7 @@ static void *exchangecal_load_calendar(void *void_data) ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name); pvt = unref_exchangecal(pvt); ao2_unlock(cal); + ast_calendar_config_release(); return NULL; } @@ -655,10 +659,11 @@ static void *exchangecal_load_calendar(void *void_data) ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name); pvt = unref_exchangecal(pvt); ao2_unlock(cal); + ast_calendar_config_release(); return NULL; } - for (v = ast_variable_browse(ast_calendar_config, cal->name); v; v = v->next) { + for (v = ast_variable_browse(cfg, cal->name); v; v = v->next) { if (!strcasecmp(v->name, "url")) { ast_string_field_set(pvt, url, v->value); } else if (!strcasecmp(v->name, "user")) { @@ -668,6 +673,8 @@ static void *exchangecal_load_calendar(void *void_data) } } + ast_calendar_config_release(); + if (ast_strlen_zero(pvt->url)) { ast_log(LOG_WARNING, "No URL was specified for Exchange calendar '%s' - skipping.\n", cal->name); pvt = unref_exchangecal(pvt); diff --git a/res/res_calendar_icalendar.c b/res/res_calendar_icalendar.c index 86024b27a..97c3253ab 100644 --- a/res/res_calendar_icalendar.c +++ b/res/res_calendar_icalendar.c @@ -324,11 +324,12 @@ static void icalendar_add_event(icalcomponent *comp, struct icaltime_span *span, static void *ical_load_calendar(void *void_data) { struct icalendar_pvt *pvt; + const struct ast_config *cfg; struct ast_variable *v; struct ast_calendar *cal = void_data; ast_mutex_t refreshlock; - if (!(cal && ast_calendar_config)) { + if (!(cal && (cfg = ast_calendar_config_acquire()))) { ast_log(LOG_ERROR, "You must enable calendar support for res_icalendar to load\n"); return NULL; } @@ -338,11 +339,13 @@ static void *ical_load_calendar(void *void_data) } else { ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n"); } + ast_calendar_config_release(); return NULL; } if (!(pvt = ao2_alloc(sizeof(*pvt), icalendar_destructor))) { ast_log(LOG_ERROR, "Could not allocate icalendar_pvt structure for calendar: %s\n", cal->name); + ast_calendar_config_release(); return NULL; } @@ -352,6 +355,7 @@ static void *ical_load_calendar(void *void_data) ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name); pvt = unref_icalendar(pvt); ao2_unlock(cal); + ast_calendar_config_release(); return NULL; } @@ -359,10 +363,11 @@ static void *ical_load_calendar(void *void_data) ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name); pvt = unref_icalendar(pvt); ao2_unlock(cal); + ast_calendar_config_release(); return NULL; } - for (v = ast_variable_browse(ast_calendar_config, cal->name); v; v = v->next) { + for (v = ast_variable_browse(cfg, cal->name); v; v = v->next) { if (!strcasecmp(v->name, "url")) { ast_string_field_set(pvt, url, v->value); } else if (!strcasecmp(v->name, "user")) { @@ -372,6 +377,8 @@ static void *ical_load_calendar(void *void_data) } } + ast_calendar_config_release(); + if (ast_strlen_zero(pvt->url)) { ast_log(LOG_WARNING, "No URL was specified for iCalendar '%s' - skipping.\n", cal->name); pvt = unref_icalendar(pvt); |