summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
Diffstat (limited to 'res')
-rw-r--r--res/res_calendar.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/res/res_calendar.c b/res/res_calendar.c
index 01f5f95c1..14846d316 100644
--- a/res/res_calendar.c
+++ b/res/res_calendar.c
@@ -216,6 +216,7 @@ static pthread_t refresh_thread = AST_PTHREADT_NULL;
static ast_mutex_t refreshlock;
static ast_cond_t refresh_condition;
static ast_mutex_t reloadlock;
+static int module_unloading;
static void event_notification_destroy(void *data);
static void *event_notification_duplicate(void *data);
@@ -1013,9 +1014,9 @@ void ast_calendar_merge_events(struct ast_calendar *cal, struct ao2_container *n
}
-static int load_config(void *data)
+static int load_config(int reload)
{
- struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
+ struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
struct ast_config *tmpcfg;
if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
@@ -1734,7 +1735,7 @@ static int reload(void)
/* Mark existing calendars for deletion */
ao2_callback(calendars, OBJ_NODATA | OBJ_MULTIPLE, cb_pending_deletion, NULL);
- load_config(NULL);
+ load_config(1);
AST_LIST_LOCK(&techs);
AST_LIST_TRAVERSE(&techs, iter, list) {
@@ -1761,15 +1762,21 @@ static void *do_refresh(void *data)
ast_mutex_lock(&refreshlock);
- if ((wait = ast_sched_wait(sched)) < 0) {
- wait = 1000;
- }
-
- ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
- ast_cond_timedwait(&refresh_condition, &refreshlock, &ts);
+ while (!module_unloading) {
+ if ((wait = ast_sched_wait(sched)) < 0) {
+ wait = 1000;
+ }
+ ts.tv_sec = (now.tv_sec + wait / 1000) + 1;
+ if (ast_cond_timedwait(&refresh_condition, &refreshlock, &ts) == ETIMEDOUT) {
+ break;
+ }
+ }
ast_mutex_unlock(&refreshlock);
+ if (module_unloading) {
+ break;
+ }
ast_sched_runq(sched);
}
@@ -1792,12 +1799,22 @@ static int unload_module(void)
/* Remove all calendars */
ao2_callback(calendars, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
+ ast_mutex_lock(&refreshlock);
+ module_unloading = 1;
+ ast_cond_signal(&refresh_condition);
+ ast_mutex_unlock(&refreshlock);
+ pthread_join(refresh_thread, NULL);
+
AST_LIST_LOCK(&techs);
- AST_LIST_TRAVERSE(&techs, tech, list) {
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&techs, tech, list) {
ast_unload_resource(tech->module, 0);
}
+ AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&techs);
+ ast_config_destroy(calendar_config);
+ calendar_config = NULL;
+
return 0;
}
@@ -1808,7 +1825,7 @@ static int load_module(void)
return AST_MODULE_LOAD_FAILURE;
}
- if (load_config(NULL)) {
+ if (load_config(0)) {
/* We don't have calendar support enabled */
return AST_MODULE_LOAD_DECLINE;
}
@@ -1835,9 +1852,6 @@ static int load_module(void)
ast_devstate_prov_add("Calendar", calendarstate);
- /* Since other modules depend on this, disable unloading */
- ast_module_ref(ast_module_info->self);
-
return AST_MODULE_LOAD_SUCCESS;
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Asterisk Calendar integration",