[asterisk-commits] twilson: branch 1.8 r353502 - /branches/1.8/res/res_calendar.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 31 17:41:45 CST 2012


Author: twilson
Date: Tue Jan 31 17:41:39 2012
New Revision: 353502

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=353502
Log:
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/

Modified:
    branches/1.8/res/res_calendar.c

Modified: branches/1.8/res/res_calendar.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_calendar.c?view=diff&rev=353502&r1=353501&r2=353502
==============================================================================
--- branches/1.8/res/res_calendar.c (original)
+++ branches/1.8/res/res_calendar.c Tue Jan 31 17:41:39 2012
@@ -204,6 +204,7 @@
 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);
@@ -960,9 +961,9 @@
 }
 
 
-static int load_config(void *data)
-{
-	struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
+static int load_config(int reload)
+{
+	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 	struct ast_config *tmpcfg;
 
 	if (!(tmpcfg = ast_config_load2("calendar.conf", "calendar", config_flags)) ||
@@ -1646,7 +1647,7 @@
 
 	/* 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) {
@@ -1673,15 +1674,21 @@
 
 		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);
 	}
 
@@ -1704,11 +1711,21 @@
 	/* 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;
 }
@@ -1720,7 +1737,7 @@
 		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;
 	}
@@ -1747,9 +1764,6 @@
 
 	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",




More information about the asterisk-commits mailing list