summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2016-03-10 21:54:03 -0600
committerRichard Mudgett <rmudgett@digium.com>2016-03-16 14:53:00 -0500
commit5f3225ddccb3bdf3673cec8f2d453be9ceb98029 (patch)
treeb680d61527f40437ad70b4a1bc99b3b01dc17b98
parent7a74971771d9bf302cb26238996eeb3cb1df7af8 (diff)
chan_sip.c: Clear scheduled immediate events on unload.
This patch is part of a series to resolve deadlocks in chan_sip.c. The reordering of chan_sip's shutdown is to handle any immediate events that get put onto the scheduler so resources aren't leaked. The typical immediate events at this time are going to be concerned with stopping other scheduled events. ASTERISK-25023 Change-Id: I3f6540717634f6f2e84d8531a054976f2bbb9d20
-rw-r--r--channels/chan_sip.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index bbe260f60..0e8b4c32b 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -34778,6 +34778,26 @@ static int unload_module(void)
ast_mutex_unlock(&monlock);
}
+ cleanup_all_regs();
+
+ {
+ struct ao2_iterator iter;
+ struct sip_subscription_mwi *iterator;
+
+ iter = ao2_iterator_init(subscription_mwi_list, 0);
+ while ((iterator = ao2_t_iterator_next(&iter, "unload_module iter"))) {
+ ao2_lock(iterator);
+ if (iterator->dnsmgr) {
+ ast_dnsmgr_release(iterator->dnsmgr);
+ iterator->dnsmgr = NULL;
+ ao2_t_ref(iterator, -1, "dnsmgr release");
+ }
+ ao2_unlock(iterator);
+ ao2_t_ref(iterator, -1, "unload_module iter");
+ }
+ ao2_iterator_destroy(&iter);
+ }
+
/* Destroy all the dialogs and free their memory */
i = ao2_iterator_init(dialogs, 0);
while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
@@ -34786,6 +34806,13 @@ static int unload_module(void)
}
ao2_iterator_destroy(&i);
+ /*
+ * Since the monitor thread runs the scheduled events and we
+ * just stopped the monitor thread above, we have to run any
+ * pending scheduled immediate events in this thread.
+ */
+ ast_sched_runq(sched);
+
/* Free memory for local network address mask */
ast_free_ha(localaddr);
@@ -34805,28 +34832,6 @@ static int unload_module(void)
ast_free(default_tls_cfg.cafile);
ast_free(default_tls_cfg.capath);
- cleanup_all_regs();
- ao2_cleanup(registry_list);
-
- {
- struct ao2_iterator iter;
- struct sip_subscription_mwi *iterator;
-
- iter = ao2_iterator_init(subscription_mwi_list, 0);
- while ((iterator = ao2_t_iterator_next(&iter, "unload_module iter"))) {
- ao2_lock(iterator);
- if (iterator->dnsmgr) {
- ast_dnsmgr_release(iterator->dnsmgr);
- iterator->dnsmgr = NULL;
- ao2_t_ref(iterator, -1, "dnsmgr release");
- }
- ao2_unlock(iterator);
- ao2_t_ref(iterator, -1, "unload_module iter");
- }
- ao2_iterator_destroy(&iter);
- }
- ao2_cleanup(subscription_mwi_list);
-
/*
* Wait awhile for the TCP/TLS thread container to become empty.
*
@@ -34842,6 +34847,9 @@ static int unload_module(void)
ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
}
+ ao2_cleanup(registry_list);
+ ao2_cleanup(subscription_mwi_list);
+
ao2_t_global_obj_release(g_bogus_peer, "Release the bogus peer.");
ao2_t_cleanup(peers, "unref the peers table");
@@ -34861,6 +34869,7 @@ static int unload_module(void)
close(sipsock);
io_context_destroy(io);
ast_sched_context_destroy(sched);
+ sched = NULL;
ast_context_destroy_by_name(used_context, "SIP");
ast_unload_realtime("sipregs");
ast_unload_realtime("sippeers");