[asterisk-commits] mjordan: trunk r374197 - in /trunk: ./ channels/ include/asterisk/ main/ res/

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


Author: mjordan
Date: Mon Oct  1 20:47:16 2012
New Revision: 374197

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

Merged revisions 374177 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 374178 from http://svn.asterisk.org/svn/asterisk/branches/10
........

Merged revisions 374196 from http://svn.asterisk.org/svn/asterisk/branches/11

Modified:
    trunk/   (props changed)
    trunk/channels/chan_agent.c
    trunk/include/asterisk/astobj2.h
    trunk/main/asterisk.c
    trunk/main/astobj2.c
    trunk/main/ccss.c
    trunk/main/cel.c
    trunk/main/channel.c
    trunk/main/config_options.c
    trunk/main/data.c
    trunk/main/db.c
    trunk/main/event.c
    trunk/main/features.c
    trunk/main/format.c
    trunk/main/format_pref.c
    trunk/main/indications.c
    trunk/main/manager.c
    trunk/main/message.c
    trunk/main/named_acl.c
    trunk/main/pbx.c
    trunk/main/taskprocessor.c
    trunk/main/udptl.c
    trunk/main/xmldoc.c
    trunk/res/res_musiconhold.c
    trunk/res/res_xmpp.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Modified: trunk/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_agent.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/channels/chan_agent.c (original)
+++ trunk/channels/chan_agent.c Mon Oct  1 20:47:16 2012
@@ -2590,12 +2590,15 @@
 	ast_format_cap_add_all(agent_tech.capabilities);
 	/* Make sure we can register our agent channel type */
 	if (ast_channel_register(&agent_tech)) {
+		agent_tech.capabilities = ast_format_cap_destroy(agent_tech.capabilities);
 		ast_log(LOG_ERROR, "Unable to register channel class 'Agent'\n");
 		return AST_MODULE_LOAD_FAILURE;
 	}
 	/* Read in the config */
-	if (!read_agent_config(0))
+	if (!read_agent_config(0)) {
+		agent_tech.capabilities = ast_format_cap_destroy(agent_tech.capabilities);
 		return AST_MODULE_LOAD_DECLINE;
+	}
 	/* Dialplan applications */
 	ast_register_application_xml(app, login_exec);
 	ast_register_application_xml(app3, agentmonitoroutgoing_exec);

Modified: trunk/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/astobj2.h?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/include/asterisk/astobj2.h (original)
+++ trunk/include/asterisk/astobj2.h Mon Oct  1 20:47:16 2012
@@ -1757,6 +1757,12 @@
  * \note they must be able to handle NULL parameters because most of the
  * allocation/find functions can fail and we don't want to try to tear
  * down a NULL */
-void ao2_cleanup(void *obj);
+void __ao2_cleanup(void *obj);
+void __ao2_cleanup_debug(void *obj, const char *file, int line, const char *function);
+#ifdef REF_DEBUG
+#define ao2_cleanup(obj) __ao2_cleanup_debug((obj), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#else
+#define ao2_cleanup(obj) __ao2_cleanup(obj)
+#endif
 void ao2_iterator_cleanup(struct ao2_iterator *iter);
 #endif /* _ASTERISK_ASTOBJ2_H */

Modified: trunk/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/asterisk.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/asterisk.c (original)
+++ trunk/main/asterisk.c Mon Oct  1 20:47:16 2012
@@ -1787,6 +1787,9 @@
 	 * (if in batch mode). really_quit happens to call it again when running
 	 * the atexit handlers, otherwise this would be a bit early. */
 	ast_cdr_engine_term();
+
+	/* Shutdown the message queue for the technology agnostic message channel.
+	 * This has to occur before we pause shutdown pending ast_undestroyed_channels. */
 	ast_msg_shutdown();
 
 	if (niceness == SHUTDOWN_NORMAL) {

Modified: trunk/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/astobj2.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/astobj2.c (original)
+++ trunk/main/astobj2.c Mon Oct  1 20:47:16 2012
@@ -544,7 +544,14 @@
 	return internal_ao2_ref(user_data, delta, __FILE__, __LINE__, __FUNCTION__);
 }
 
-void ao2_cleanup(void *obj)
+void __ao2_cleanup_debug(void *obj, const char *file, int line, const char *function)
+{
+	if (obj) {
+		__ao2_ref_debug(obj, -1, "ao2_cleanup", file, line, function);
+	}
+}
+
+void __ao2_cleanup(void *obj)
 {
 	if (obj) {
 		ao2_ref(obj, -1);
@@ -1347,7 +1354,11 @@
 				node->obj = NULL;
 
 				/* Unref the node from the container. */
-				__ao2_ref(node, -1);
+				if (tag) {
+					__ao2_ref_debug(node, -1, tag, file, line, func);
+				} else {
+					__ao2_ref(node, -1);
+				}
 			}
 		}
 
@@ -1488,7 +1499,11 @@
 	ao2_iterator_restart(iter);
 
 	/* Release the iterated container reference. */
+#if defined(REF_DEBUG)
+	__ao2_ref_debug(iter->c, -1, "ao2_iterator_destroy", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+#else
 	ao2_ref(iter->c, -1);
+#endif
 	iter->c = NULL;
 
 	/* Free the malloced iterator. */
@@ -2002,7 +2017,12 @@
 	struct hash_bucket_node *node;
 	int i;
 
+#if defined(REF_DEBUG)
+	node = __ao2_alloc_debug(sizeof(*node), hash_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK,
+			"hash_ao2_new_node", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1);
+#else
 	node = __ao2_alloc(sizeof(*node), hash_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
+#endif
 	if (!node) {
 		return NULL;
 	}
@@ -3366,12 +3386,22 @@
 };
 #endif	/* defined(AO2_DEBUG) || defined(AST_DEVMODE) */
 
+#if defined(AST_DEVMODE)
+static void astobj2_cleanup(void)
+{
+	ao2_ref(reg_containers, -1);
+}
+#endif
 
 int astobj2_init(void)
 {
 #if defined(AST_DEVMODE)
 	reg_containers = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_RWLOCK,
 		AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, ao2_reg_sort_cb, NULL);
+	if (!reg_containers) {
+		return -1;
+	}
+	ast_register_atexit(astobj2_cleanup);
 #endif	/* defined(AST_DEVMODE) */
 #if defined(AO2_DEBUG) || defined(AST_DEVMODE)
 	ast_cli_register_multiple(cli_astobj2, ARRAY_LEN(cli_astobj2));

Modified: trunk/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/ccss.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/ccss.c (original)
+++ trunk/main/ccss.c Mon Oct  1 20:47:16 2012
@@ -4520,6 +4520,31 @@
 	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_context) {
+		ast_sched_context_destroy(cc_sched_context);
+		cc_sched_context = NULL;
+	}
+	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;
@@ -4557,5 +4582,7 @@
 	initialize_cc_devstate_map();
 	res |= ast_devstate_prov_add("ccss", ccss_device_state);
 
+	ast_register_atexit(cc_shutdown);
+
 	return res;
 }

Modified: trunk/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/cel.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/cel.c (original)
+++ trunk/main/cel.c Mon Oct  1 20:47:16 2012
@@ -716,6 +716,10 @@
 		ao2_ref(appset, -1);
 		appset = NULL;
 	}
+	if (linkedids) {
+		ao2_ref(linkedids, -1);
+		linkedids = NULL;
+	}
 }
 
 int ast_cel_engine_init(void)

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Mon Oct  1 20:47:16 2012
@@ -8553,6 +8553,15 @@
 	AST_DATA_ENTRY("/asterisk/core/channeltypes", &channeltypes_provider),
 };
 
+static void channels_shutdown(void)
+{
+	ast_data_unregister(NULL);
+	if (channels) {
+		ao2_container_unregister("channels");
+		ao2_ref(channels, -1);
+	}
+}
+
 void ast_channels_init(void)
 {
 	channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
@@ -8566,6 +8575,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: trunk/main/config_options.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/config_options.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/config_options.c (original)
+++ trunk/main/config_options.c Mon Oct  1 20:47:16 2012
@@ -158,6 +158,8 @@
 			}
 			return -1;
 		}
+		/* The container should hold the only ref to opt */
+		ao2_ref(opt, -1);
 	}
 	return 0;
 }

Modified: trunk/main/data.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/data.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/data.c (original)
+++ trunk/main/data.c Mon Oct  1 20:47:16 2012
@@ -3314,6 +3314,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;
@@ -3333,5 +3341,7 @@
 	AST_TEST_REGISTER(test_data_get);
 #endif
 
+	ast_register_atexit(data_shutdown);
+
 	return res;
 }

Modified: trunk/main/db.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/db.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/db.c (original)
+++ trunk/main/db.c Mon Oct  1 20:47:16 2012
@@ -946,8 +946,14 @@
 	return NULL;
 }
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
 static void astdb_atexit(void)
 {
+	ast_manager_unregister("DBGet");
+	ast_manager_unregister("DBPut");
+	ast_manager_unregister("DBDel");
+	ast_manager_unregister("DBDelTree");
+
 	/* Set doexit to 1 to kill thread. db_sync must be called with
 	 * mutex held. */
 	doexit = 1;

Modified: trunk/main/event.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/event.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/event.c (original)
+++ trunk/main/event.c Mon Oct  1 20:47:16 2012
@@ -1811,6 +1811,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;
@@ -1827,17 +1859,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: trunk/main/features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/features.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/features.c (original)
+++ trunk/main/features.c Mon Oct  1 20:47:16 2012
@@ -7023,7 +7023,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);
@@ -8958,6 +8957,24 @@
 	.write = featuremap_write
 };
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void features_shutdown(void)
+{
+	ast_devstate_prov_del("Park");
+	ast_custom_function_unregister(&featuremap_function);
+	ast_custom_function_unregister(&feature_function);
+	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;
@@ -8993,6 +9010,8 @@
 	res |= AST_TEST_REGISTER(features_test);
 #endif	/* defined(TEST_FRAMEWORK) */
 
+	ast_register_atexit(features_shutdown);
+
 	return res;
 }
 

Modified: trunk/main/format.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/format.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/format.c (original)
+++ trunk/main/format.c Mon Oct  1 20:47:16 2012
@@ -957,6 +957,7 @@
 	entry->custom_entry = 0;
 
 	ao2_link(format_list, entry);
+	ao2_ref(entry, -1);
 	return 0;
 }
 
@@ -1025,6 +1026,7 @@
 	ast_rwlock_unlock(&format_list_array_lock);
 	return 0;
 }
+
 static int format_list_init(void)
 {
 	struct ast_format tmpfmt;
@@ -1074,6 +1076,20 @@
 	return 0;
 }
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void format_list_shutdown(void)
+{
+	ast_rwlock_destroy(&format_list_array_lock);
+	if (format_list) {
+		ao2_t_ref(format_list, -1, "Unref format_list container in shutdown");
+		format_list = NULL;
+	}
+	if (format_list_array) {
+		ao2_t_ref(format_list_array, -1, "Unref format_list_array in shutdown");
+		format_list_array = NULL;
+	}
+}
+
 int ast_format_list_init(void)
 {
 	if (ast_rwlock_init(&format_list_array_lock)) {
@@ -1086,15 +1102,21 @@
 		goto init_list_cleanup;
 	}
 
+	ast_register_atexit(format_list_shutdown);
 	return 0;
 init_list_cleanup:
 
-	ast_rwlock_destroy(&format_list_array_lock);
-	ao2_ref(format_list, -1);
-	if (format_list_array) {
-		ao2_ref(format_list_array, -1);
-	}
+	format_list_shutdown();
 	return -1;
+}
+
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void format_attr_shutdown(void)
+{
+	if (interfaces) {
+		ao2_ref(interfaces, -1);
+		interfaces = NULL;
+	}
 }
 
 int ast_format_attr_init(void)
@@ -1106,6 +1128,7 @@
 	if (!interfaces) {
 		return -1;
 	}
+	ast_register_atexit(format_attr_shutdown);
 	return 0;
 }
 
@@ -1371,7 +1394,7 @@
 			ast_rtp_engine_load_format(&f_list[x].format);
 		}
 	}
-
+	f_list = ast_format_list_destroy(f_list);
 	return 0;
 }
 
@@ -1405,6 +1428,6 @@
 
 	/* This will remove all custom formats previously created for this interface */
 	load_format_config();
-
-	return 0;
-}
+	f_list = ast_format_list_destroy(f_list);
+	return 0;
+}

Modified: trunk/main/format_pref.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/format_pref.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/format_pref.c (original)
+++ trunk/main/format_pref.c Mon Oct  1 20:47:16 2012
@@ -285,6 +285,7 @@
 
 	if (idx < 0) {
 		ast_log(AST_LOG_WARNING, "Format %s unknown; unable to get preferred codec packet size\n", ast_getformatname(format));
+		ast_format_list_destroy(f_list);
 		return fmt;
 	}
 

Modified: trunk/main/indications.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/indications.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/indications.c (original)
+++ trunk/main/indications.c Mon Oct  1 20:47:16 2012
@@ -1150,6 +1150,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)
 {
@@ -1164,6 +1173,7 @@
 
 	ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications));
 
+	ast_register_atexit(indications_shutdown);
 	return 0;
 }
 

Modified: trunk/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/manager.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Mon Oct  1 20:47:16 2012
@@ -7225,6 +7225,66 @@
 	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("PresenceState");
+		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");
+		ast_custom_function_unregister(&managerclient_function);
+	}
+
+#ifdef AST_XML_DOCS
+	ao2_t_global_obj_release(event_docs, "Dispose of event_docs");
+#endif
+
+	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, int by_external_config)
 {
 	struct ast_config *ucfg = NULL, *cfg = NULL;
@@ -7295,12 +7355,12 @@
 #ifdef AST_XML_DOCS
 	temp_event_docs = ast_xmldoc_build_documentation("managerEvent");
 	if (temp_event_docs) {
-		temp_event_docs = ao2_global_obj_replace(event_docs, temp_event_docs);
-		if (temp_event_docs) {
-			ao2_ref(temp_event_docs, -1);
-		}
+		ao2_t_global_obj_replace_unref(event_docs, temp_event_docs, "Toss old event docs");
+		ao2_t_ref(temp_event_docs, -1, "Remove creation ref - container holds only ref now");
 	}
 #endif
+
+	ast_register_atexit(manager_shutdown);
 
 	if ((cfg = ast_config_load2("manager.conf", "manager", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
 		return 0;
@@ -7700,6 +7760,7 @@
 	} else if (ast_ssl_setup(amis_desc.tls_cfg)) {
 		ast_tcptls_server_start(&amis_desc);
 	}
+
 	return 0;
 }
 

Modified: trunk/main/message.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/message.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/message.c (original)
+++ trunk/main/message.c Mon Oct  1 20:47:16 2012
@@ -1302,6 +1302,30 @@
 	return 0;
 }
 
+void ast_msg_shutdown()
+{
+	if (msg_q_tp) {
+		msg_q_tp = ast_taskprocessor_unreference(msg_q_tp);
+	}
+}
+
+/*! \internal \brief Clean up other resources on Asterisk shutdown
+ * \note This does not include the msg_q_tp object, which must be disposed
+ * of prior to Asterisk checking for channel destruction in its shutdown
+ * sequence.  The atexit handlers are executed after this occurs. */
+static void message_shutdown(void)
+{
+	ast_custom_function_unregister(&msg_function);
+	ast_custom_function_unregister(&msg_data_function);
+	ast_unregister_application(app_msg_send);
+	ast_manager_unregister("MessageSend");
+
+	if (msg_techs) {
+		ao2_ref(msg_techs, -1);
+		msg_techs = NULL;
+	}
+}
+
 /*
  * \internal
  * \brief Initialize stuff during Asterisk startup.
@@ -1331,10 +1355,7 @@
 	res |= ast_register_application2(app_msg_send, msg_send_exec, NULL, NULL, NULL);
 	res |= ast_manager_register_xml_core("MessageSend", EVENT_FLAG_MESSAGE, action_messagesend);
 
+	ast_register_atexit(message_shutdown);
+
 	return res;
 }
-
-void ast_msg_shutdown(void)
-{
-	msg_q_tp = ast_taskprocessor_unreference(msg_q_tp);
-}

Modified: trunk/main/named_acl.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/named_acl.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/named_acl.c (original)
+++ trunk/main/named_acl.c Mon Oct  1 20:47:16 2012
@@ -545,6 +545,7 @@
 	aco_option_register(&cfg_info, "deny", ACO_EXACT, named_acl_types, NULL, OPT_ACL_T, 0, FLDSET(struct named_acl, ha));
 
 	if (aco_process_config(&cfg_info, 0)) {
+		aco_info_destroy(&cfg_info);
 		return 0;
 	}
 

Modified: trunk/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/pbx.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Mon Oct  1 20:47:16 2012
@@ -11488,6 +11488,32 @@
 	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 (presence_state_sub) {
+		presence_state_sub = ast_event_unsubscribe(presence_state_sub);
+	}
+	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);
+	if (extension_state_tps) {
+		extension_state_tps = ast_taskprocessor_unreference(extension_state_tps);
+	}
+}
+
 int load_pbx(void)
 {
 	int x;
@@ -11526,6 +11552,7 @@
 		return -1;
 	}
 
+	ast_register_atexit(unload_pbx);
 	return 0;
 }
 
@@ -11886,11 +11913,26 @@
 	return (state_cb->change_cb == change_cb) ? CMP_MATCH | CMP_STOP : 0;
 }
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void pbx_shutdown(void)
+{
+	if (hints) {
+		ao2_ref(hints, -1);
+	}
+	if (hintdevices) {
+		ao2_ref(hintdevices, -1);
+	}
+	if (statecbs) {
+		ao2_ref(statecbs, -1);
+	}
+}
+
 int ast_pbx_init(void)
 {
 	hints = ao2_container_alloc(HASH_EXTENHINT_SIZE, hint_hash, hint_cmp);
 	hintdevices = ao2_container_alloc(HASH_EXTENHINT_SIZE, hintdevice_hash_cb, hintdevice_cmp_multiple);
 	statecbs = ao2_container_alloc(1, NULL, statecbs_cmp);
 
+	ast_register_atexit(pbx_shutdown);
 	return (hints && hintdevices && statecbs) ? 0 : -1;
 }

Modified: trunk/main/taskprocessor.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/taskprocessor.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/taskprocessor.c (original)
+++ trunk/main/taskprocessor.c Mon Oct  1 20:47:16 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: trunk/main/udptl.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/udptl.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/udptl.c (original)
+++ trunk/main/udptl.c Mon Oct  1 20:47:16 2012
@@ -1462,6 +1462,13 @@
 	return 0;
 }
 
+/*! \internal \brief Clean up resources on Asterisk shutdown */
+static void udptl_shutdown(void)
+{
+	ao2_t_global_obj_release(globals, "Unref udptl global container in shutdown");
+	aco_info_destroy(&cfg_info);
+}
+
 void ast_udptl_init(void)
 {
 	if (aco_info_init(&cfg_info)) {
@@ -1496,4 +1503,6 @@
 	ast_cli_register_multiple(cli_udptl, ARRAY_LEN(cli_udptl));
 
 	__ast_udptl_reload(0);
-}
+
+	ast_register_atexit(udptl_shutdown);
+}

Modified: trunk/main/xmldoc.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/xmldoc.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/main/xmldoc.c (original)
+++ trunk/main/xmldoc.c Mon Oct  1 20:47:16 2012
@@ -2279,6 +2279,7 @@
 
 			if (item) {
 				ao2_link(docs, item);
+				ao2_t_ref(item, -1, "Dispose of creation ref");
 				item = NULL;
 			}
 		}

Modified: trunk/res/res_musiconhold.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_musiconhold.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/res/res_musiconhold.c (original)
+++ trunk/res/res_musiconhold.c Mon Oct  1 20:47:16 2012
@@ -1828,7 +1828,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)

Modified: trunk/res/res_xmpp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_xmpp.c?view=diff&rev=374197&r1=374196&r2=374197
==============================================================================
--- trunk/res/res_xmpp.c (original)
+++ trunk/res/res_xmpp.c Mon Oct  1 20:47:16 2012
@@ -4375,6 +4375,7 @@
 	aco_option_register_custom(&cfg_info, "buddy", ACO_EXACT, client_options, NULL, client_buddy_handler, 0);
 
 	if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
+		aco_info_destroy(&cfg_info);
 		return AST_MODULE_LOAD_DECLINE;
 	}
 




More information about the asterisk-commits mailing list