aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/calendar.h14
-rw-r--r--res/res_calendar.c40
-rw-r--r--res/res_calendar_caldav.c11
-rw-r--r--res/res_calendar_exchange.c11
-rw-r--r--res/res_calendar_icalendar.c11
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);