summaryrefslogtreecommitdiff
path: root/res/res_calendar.c
diff options
context:
space:
mode:
authorTerry Wilson <twilson@digium.com>2012-02-01 00:08:27 +0000
committerTerry Wilson <twilson@digium.com>2012-02-01 00:08:27 +0000
commit5861bab06d486523c041ec4ecc69a579eaaa64f0 (patch)
tree01b1a5460045ef8fd61bb41cce69111e15079d8a /res/res_calendar.c
parent2d7a40de5842885dd6a2e892640900c898576eb0 (diff)
Allow res_calendar to be unloaded
The calendaring tech modules depend on res_calendar and initially res_calendar just bumped the use count so that it couldn't be unloaded. res_calendar can potentially create many threads and I've seen issues where the Asterisk shutdown has failed where it looked like these threads could be the culprit. This patch adds unload support for res_calendar. Unloading res_calendar will also unload the dependant tech modules as well. (closes issue ASTERISK-16744) Review: https://reviewboard.asterisk.org/r/1657/ ........ Merged revisions 353502 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 353503 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@353504 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_calendar.c')
-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",