[svn-commits] rmudgett: branch 13 r433596 - /branches/13/res/res_pjsip_registrar_expire.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Mar 27 12:50:58 CDT 2015


Author: rmudgett
Date: Fri Mar 27 12:50:51 2015
New Revision: 433596

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=433596
Log:
res_pjsip_registrar_expire.c: Cleanup scheduler leaks on unload/shutdown.

Contact expiration object refs were leaked when the module was unloaded.

* Made empty the scheduler of entries before destroying it to release the
object ref held by the scheduler entry.

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

Modified:
    branches/13/res/res_pjsip_registrar_expire.c

Modified: branches/13/res/res_pjsip_registrar_expire.c
URL: http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_registrar_expire.c?view=diff&rev=433596&r1=433595&r2=433596
==============================================================================
--- branches/13/res/res_pjsip_registrar_expire.c (original)
+++ branches/13/res/res_pjsip_registrar_expire.c Fri Mar 27 12:50:51 2015
@@ -175,56 +175,66 @@
 	ao2_callback(contacts, OBJ_NODATA, contact_expiration_setup, NULL);
 }
 
+static int unload_observer_delete(void *obj, void *arg, int flags)
+{
+	struct contact_expiration *expiration = obj;
+
+	AST_SCHED_DEL_UNREF(sched, expiration->sched, ao2_cleanup(expiration));
+	return CMP_MATCH;
+}
+
+static int unload_module(void)
+{
+	ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &contact_expiration_observer);
+	if (sched) {
+		ao2_callback(contact_autoexpire, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK,
+			unload_observer_delete, NULL);
+		ast_sched_context_destroy(sched);
+		sched = NULL;
+	}
+	ao2_cleanup(contact_autoexpire);
+	contact_autoexpire = NULL;
+
+	return 0;
+}
+
 static int load_module(void)
 {
 	CHECK_PJSIP_MODULE_LOADED();
 
-	if (!(contact_autoexpire = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, CONTACT_AUTOEXPIRE_BUCKETS,
-		contact_expiration_hash, contact_expiration_cmp))) {
+	contact_autoexpire = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK,
+		CONTACT_AUTOEXPIRE_BUCKETS, contact_expiration_hash, contact_expiration_cmp);
+	if (!contact_autoexpire) {
 		ast_log(LOG_ERROR, "Could not create container for contact auto-expiration\n");
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Could not create scheduler for contact auto-expiration\n");
-		goto error;
+		unload_module();
+		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	if (ast_sched_start_thread(sched)) {
 		ast_log(LOG_ERROR, "Could not start scheduler thread for contact auto-expiration\n");
-		goto error;
+		unload_module();
+		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	contact_expiration_initialize_existing();
 
 	if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &contact_expiration_observer)) {
 		ast_log(LOG_ERROR, "Could not add observer for notifications about contacts for contact auto-expiration\n");
-		goto error;
+		unload_module();
+		return AST_MODULE_LOAD_FAILURE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
-
-error:
-	if (sched) {
-		ast_sched_context_destroy(sched);
-	}
-
-	ao2_cleanup(contact_autoexpire);
-	return AST_MODULE_LOAD_FAILURE;
-}
-
-static int unload_module(void)
-{
-	ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &contact_expiration_observer);
-	ast_sched_context_destroy(sched);
-	ao2_cleanup(contact_autoexpire);
-
-	return 0;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Contact Auto-Expiration",
-		.support_level = AST_MODULE_SUPPORT_CORE,
-		.load = load_module,
-		.unload = unload_module,
-		.load_pri = AST_MODPRI_APP_DEPEND,
-	       );
+	.support_level = AST_MODULE_SUPPORT_CORE,
+	.load = load_module,
+	.unload = unload_module,
+	.load_pri = AST_MODPRI_APP_DEPEND,
+	);




More information about the svn-commits mailing list