summaryrefslogtreecommitdiff
path: root/channels
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:44:43 -0500
commit52f0932e4c6d4446afbbf0f0ffa0ac8f50593ff4 (patch)
tree95f20bf0f583cbea4773f435cc409e9ef422e5e2 /channels
parent0987a11cce90da40f5a6bec4646474c34dc55bc2 (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
Diffstat (limited to 'channels')
-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 a8d503206..271937208 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -34879,6 +34879,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"))) {
@@ -34887,6 +34907,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);
@@ -34908,28 +34935,6 @@ static int unload_module(void)
ast_rtp_dtls_cfg_free(&default_dtls_cfg);
- 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.
*
@@ -34945,6 +34950,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");
@@ -34964,6 +34972,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");