summaryrefslogtreecommitdiff
path: root/res/res_pjsip_registrar_expire.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-03-27 20:23:58 +0000
committerRichard Mudgett <rmudgett@digium.com>2015-03-27 20:23:58 +0000
commita18da4eaf20223b0d20754dc51f769da53909fdb (patch)
tree210dfcb8f002206084917f4553cbd05eceb4de70 /res/res_pjsip_registrar_expire.c
parentcb1c639817ddd48b7b623f55c3412b90cb407959 (diff)
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/ ........ Merged revisions 433596 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@433617 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_registrar_expire.c')
-rw-r--r--res/res_pjsip_registrar_expire.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/res/res_pjsip_registrar_expire.c b/res/res_pjsip_registrar_expire.c
index 256ed9e1b..c311c0025 100644
--- a/res/res_pjsip_registrar_expire.c
+++ b/res/res_pjsip_registrar_expire.c
@@ -175,56 +175,66 @@ static void contact_expiration_initialize_existing(void)
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,
+ );