[asterisk-commits] mjordan: branch 1.8 r374177 - in /branches/1.8: main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Oct 1 19:31:21 CDT 2012


Author: mjordan
Date: Mon Oct  1 19:31:14 2012
New Revision: 374177

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=374177
Log:
Fix a variety of ref counting issues

This patch resolves a number of ref leaks that occur primarily on Asterisk
shutdown.  It adds a variety of shutdown routines to core portions of
Asterisk such that they can reclaim resources allocate duringd initialization.

Review: https://reviewboard.asterisk.org/r/2137


Modified:
    branches/1.8/main/ccss.c
    branches/1.8/main/cel.c
    branches/1.8/main/channel.c
    branches/1.8/main/data.c
    branches/1.8/main/event.c
    branches/1.8/main/features.c
    branches/1.8/main/indications.c
    branches/1.8/main/manager.c
    branches/1.8/main/pbx.c
    branches/1.8/main/taskprocessor.c
    branches/1.8/res/res_musiconhold.c

Modified: branches/1.8/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/ccss.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/ccss.c (original)
+++ branches/1.8/main/ccss.c Mon Oct  1 19:31:14 2012
@@ -4310,6 +4310,30 @@
 	AST_CLI_DEFINE(handle_cc_kill, "Kill a CC transaction"),
 };
 
+static void cc_shutdown(void)
+{
+	ast_devstate_prov_del("ccss");
+	ast_cc_agent_unregister(&generic_agent_callbacks);
+	ast_cc_monitor_unregister(&generic_monitor_cbs);
+	ast_unregister_application(cccancel_app);
+	ast_unregister_application(ccreq_app);
+
+	if (cc_sched_thread) {
+		cc_sched_thread = ast_sched_thread_destroy(cc_sched_thread);
+	}
+	if (cc_core_taskprocessor) {
+		cc_core_taskprocessor = ast_taskprocessor_unreference(cc_core_taskprocessor);
+	}
+	if (generic_monitors) {
+		ao2_t_ref(generic_monitors, -1, "Unref generic_monitor container in cc_shutdown");
+		generic_monitors = NULL;
+	}
+	if (cc_core_instances) {
+		ao2_t_ref(cc_core_instances, -1, "Unref cc_core_instances container in cc_shutdown");
+		cc_core_instances = NULL;
+	}
+}
+
 int ast_cc_init(void)
 {
 	int res;
@@ -4338,5 +4362,6 @@
 	cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME);
 	dialed_cc_interface_counter = 1;
 	initialize_cc_max_requests();
+	ast_register_atexit(cc_shutdown);
 	return res;
 }

Modified: branches/1.8/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/cel.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/cel.c (original)
+++ branches/1.8/main/cel.c Mon Oct  1 19:31:14 2012
@@ -711,6 +711,10 @@
 		ao2_ref(appset, -1);
 		appset = NULL;
 	}
+	if (linkedids) {
+		ao2_ref(linkedids, -1);
+		linkedids = NULL;
+	}
 }
 
 int ast_cel_engine_init(void)

Modified: branches/1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/channel.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/channel.c (original)
+++ branches/1.8/main/channel.c Mon Oct  1 19:31:14 2012
@@ -8062,6 +8062,15 @@
 	AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
 };
 
+static void channels_shutdown(void)
+{
+	ast_data_unregister(NULL);
+	if (channels) {
+		ao2_ref(channels, -1);
+		channels = NULL;
+	}
+}
+
 void ast_channels_init(void)
 {
 	channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
@@ -8072,6 +8081,8 @@
 	ast_data_register_multiple_core(channel_providers, ARRAY_LEN(channel_providers));
 
 	ast_plc_reload();
+
+	ast_register_atexit(channels_shutdown);
 }
 
 /*! \brief Print call group and pickup group ---*/

Modified: branches/1.8/main/data.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/data.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/data.c (original)
+++ branches/1.8/main/data.c Mon Oct  1 19:31:14 2012
@@ -3282,6 +3282,14 @@
 
 #endif
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void data_shutdown(void)
+{
+	ast_manager_unregister("DataGet");
+	ao2_t_ref(root_data.container, -1, "Unref root_data.container in data_shutdown");
+	ast_rwlock_destroy(&root_data.lock);
+}
+
 int ast_data_init(void)
 {
 	int res = 0;
@@ -3301,5 +3309,7 @@
 	AST_TEST_REGISTER(test_data_get);
 #endif
 
+	ast_register_atexit(data_shutdown);
+
 	return res;
 }

Modified: branches/1.8/main/event.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/event.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/event.c (original)
+++ branches/1.8/main/event.c Mon Oct  1 19:31:14 2012
@@ -1777,6 +1777,38 @@
 	AST_CLI_DEFINE(event_dump_cache, "Dump the internal event cache (for debugging)"),
 };
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void event_shutdown(void)
+{
+	struct ast_event_sub *sub;
+	int i;
+
+	if (event_dispatcher) {
+		event_dispatcher = ast_taskprocessor_unreference(event_dispatcher);
+	}
+
+	/* Remove any remaining subscriptions.  Note that we can't just call
+	 * unsubscribe, as it will attempt to lock the subscription list
+	 * as well */
+	for (i = 0; i < AST_EVENT_TOTAL; i++) {
+		AST_RWDLLIST_WRLOCK(&ast_event_subs[i]);
+		while ((sub = AST_RWDLLIST_REMOVE_HEAD(&ast_event_subs[i], entry))) {
+			ast_event_sub_destroy(sub);
+		}
+		AST_RWDLLIST_UNLOCK(&ast_event_subs[i]);
+		AST_RWDLLIST_HEAD_DESTROY(&ast_event_subs[i]);
+	}
+
+	for (i = 0; i < AST_EVENT_TOTAL; i++) {
+		if (!ast_event_cache[i].hash_fn) {
+			continue;
+		}
+		if (ast_event_cache[i].container) {
+			ao2_ref(ast_event_cache[i].container, -1);
+		}
+	}
+}
+
 int ast_event_init(void)
 {
 	int i;
@@ -1793,17 +1825,23 @@
 
 		if (!(ast_event_cache[i].container = ao2_container_alloc(NUM_CACHE_BUCKETS,
 				ast_event_hash, ast_event_cmp))) {
-			return -1;
+			goto event_init_cleanup;
 		}
 	}
 
 	if (!(event_dispatcher = ast_taskprocessor_get("core_event_dispatcher", 0))) {
-		return -1;
+		goto event_init_cleanup;
 	}
 
 	ast_cli_register_multiple(event_cli, ARRAY_LEN(event_cli));
 
+	ast_register_atexit(event_shutdown);
+
 	return 0;
+
+event_init_cleanup:
+	event_shutdown();
+	return -1;
 }
 
 size_t ast_event_minimum_length(void)

Modified: branches/1.8/main/features.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/features.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/features.c (original)
+++ branches/1.8/main/features.c Mon Oct  1 19:31:14 2012
@@ -6644,7 +6644,6 @@
 			return -1;
 		}
 		ast_debug(1, "Configuration of default default parking lot done.\n");
-		parkinglot_addref(default_parkinglot);
 	}
 
 	cfg = ast_config_load2("features.conf", "features", config_flags);
@@ -8221,6 +8220,22 @@
 }
 #endif	/* defined(TEST_FRAMEWORK) */
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void features_shutdown(void)
+{
+	ast_devstate_prov_del("Park");
+	ast_manager_unregister("Bridge");
+	ast_manager_unregister("Park");
+	ast_manager_unregister("Parkinglots");
+	ast_manager_unregister("ParkedCalls");
+	ast_unregister_application(parkcall);
+	ast_unregister_application(parkedcall);
+	ast_unregister_application(app_bridge);
+
+	pthread_cancel(parking_thread);
+	ao2_ref(parkinglots, -1);
+}
+
 int ast_features_init(void)
 {
 	int res;
@@ -8253,5 +8268,7 @@
 	res |= AST_TEST_REGISTER(features_test);
 #endif	/* defined(TEST_FRAMEWORK) */
 
+	ast_register_atexit(features_shutdown);
+
 	return res;
 }

Modified: branches/1.8/main/indications.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/indications.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/indications.c (original)
+++ branches/1.8/main/indications.c Mon Oct  1 19:31:14 2012
@@ -1149,6 +1149,15 @@
 	return 0;
 }
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void indications_shutdown(void)
+{
+	if (ast_tone_zones) {
+		ao2_ref(ast_tone_zones, -1);
+		ast_tone_zones = NULL;
+	}
+}
+
 /*! \brief Load indications module */
 int ast_indications_init(void)
 {
@@ -1163,6 +1172,7 @@
 
 	ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications));
 
+	ast_register_atexit(indications_shutdown);
 	return 0;
 }
 

Modified: branches/1.8/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/manager.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/manager.c (original)
+++ branches/1.8/main/manager.c Mon Oct  1 19:31:14 2012
@@ -6584,6 +6584,61 @@
 	AST_RWLIST_UNLOCK(&channelvars);
 }
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void manager_shutdown(void)
+{
+	struct ast_manager_user *user;
+
+	if (registered) {
+		ast_manager_unregister("Ping");
+		ast_manager_unregister("Events");
+		ast_manager_unregister("Logoff");
+		ast_manager_unregister("Login");
+		ast_manager_unregister("Challenge");
+		ast_manager_unregister("Hangup");
+		ast_manager_unregister("Status");
+		ast_manager_unregister("Setvar");
+		ast_manager_unregister("Getvar");
+		ast_manager_unregister("GetConfig");
+		ast_manager_unregister("GetConfigJSON");
+		ast_manager_unregister("UpdateConfig");
+		ast_manager_unregister("CreateConfig");
+		ast_manager_unregister("ListCategories");
+		ast_manager_unregister("Redirect");
+		ast_manager_unregister("Atxfer");
+		ast_manager_unregister("Originate");
+		ast_manager_unregister("Command");
+		ast_manager_unregister("ExtensionState");
+		ast_manager_unregister("AbsoluteTimeout");
+		ast_manager_unregister("MailboxStatus");
+		ast_manager_unregister("MailboxCount");
+		ast_manager_unregister("ListCommands");
+		ast_manager_unregister("SendText");
+		ast_manager_unregister("UserEvent");
+		ast_manager_unregister("WaitEvent");
+		ast_manager_unregister("CoreSettings");
+		ast_manager_unregister("CoreStatus");
+		ast_manager_unregister("Reload");
+		ast_manager_unregister("CoreShowChannels");
+		ast_manager_unregister("ModuleLoad");
+		ast_manager_unregister("ModuleCheck");
+		ast_manager_unregister("AOCMessage");
+		ast_manager_unregister("Filter");
+	}
+
+	if (sessions) {
+		ao2_ref(sessions, -1);
+		sessions = NULL;
+	}
+
+	while ((user = AST_LIST_REMOVE_HEAD(&users, list))) {
+		ao2_ref(user->whitefilters, -1);
+		ao2_ref(user->blackfilters, -1);
+		ast_free(user);
+	}
+}
+
+
 static int __init_manager(int reload)
 {
 	struct ast_config *ucfg = NULL, *cfg = NULL;
@@ -6641,6 +6696,9 @@
 		/* Append placeholder event so master_eventq never runs dry */
 		append_event("Event: Placeholder\r\n\r\n", 0);
 	}
+
+	ast_register_atexit(manager_shutdown);
+
 	if ((cfg = ast_config_load2("manager.conf", "manager", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
 		return 0;
 	}
@@ -7017,6 +7075,7 @@
 	} else if (ast_ssl_setup(amis_desc.tls_cfg)) {
 		ast_tcptls_server_start(&amis_desc);
 	}
+
 	return 0;
 }
 

Modified: branches/1.8/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/pbx.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/pbx.c (original)
+++ branches/1.8/main/pbx.c Mon Oct  1 19:31:14 2012
@@ -10301,6 +10301,26 @@
 	AST_DATA_ENTRY("asterisk/core/hints", &hints_data_provider),
 };
 
+/*! \internal \brief Clean up resources on Asterisk shutdown.
+ * \note Cleans up resources allocated in load_pbx */
+static void unload_pbx(void)
+{
+	int x;
+
+	if (device_state_sub) {
+		device_state_sub = ast_event_unsubscribe(device_state_sub);
+	}
+
+	/* Unregister builtin applications */
+	for (x = 0; x < ARRAY_LEN(builtins); x++) {
+		ast_unregister_application(builtins[x].name);
+	}
+	ast_manager_unregister("ShowDialPlan");
+	ast_custom_function_unregister(&exception_function);
+	ast_custom_function_unregister(&testtime_function);
+	ast_data_unregister(NULL);
+}
+
 int load_pbx(void)
 {
 	int x;
@@ -10334,6 +10354,7 @@
 		return -1;
 	}
 
+	ast_register_atexit(unload_pbx);
 	return 0;
 }
 

Modified: branches/1.8/main/taskprocessor.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/taskprocessor.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/main/taskprocessor.c (original)
+++ branches/1.8/main/taskprocessor.c Mon Oct  1 19:31:14 2012
@@ -122,6 +122,12 @@
 	AST_CLI_DEFINE(cli_tps_report, "List instantiated task processors and statistics"),
 };
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void tps_shutdown(void)
+{
+	ao2_t_ref(tps_singletons, -1, "Unref tps_singletons in shutdown");
+}
+
 /* initialize the taskprocessor container and register CLI operations */
 int ast_tps_init(void)
 {
@@ -133,6 +139,9 @@
 	ast_cond_init(&cli_ping_cond, NULL);
 
 	ast_cli_register_multiple(taskprocessor_clis, ARRAY_LEN(taskprocessor_clis));
+
+	ast_register_atexit(tps_shutdown);
+
 	return 0;
 }
 

Modified: branches/1.8/res/res_musiconhold.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_musiconhold.c?view=diff&rev=374177&r1=374176&r2=374177
==============================================================================
--- branches/1.8/res/res_musiconhold.c (original)
+++ branches/1.8/res/res_musiconhold.c Mon Oct  1 19:31:14 2012
@@ -1776,7 +1776,11 @@
 static void ast_moh_destroy(void)
 {
 	ast_verb(2, "Destroying musiconhold processes\n");
-	ao2_t_callback(mohclasses, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Destroy callback");
+	if (mohclasses) {
+		ao2_t_callback(mohclasses, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "Destroy callback");
+		ao2_ref(mohclasses, -1);
+		mohclasses = NULL;
+	}
 }
 
 static char *handle_cli_moh_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)




More information about the asterisk-commits mailing list