summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2016-12-08 21:00:02 -0500
committerCorey Farrell <git@cfware.com>2016-12-17 11:32:14 -0500
commit493849dcd7224145388fac81bc791d219f17aae1 (patch)
tree6cdba76c727ca7f8d6610e9c3af5762c60e8e38d /channels
parent91485734a48e9e44292b80b8993fb464bc3817b0 (diff)
chan_sip: Reorder unload_module to deal with stuck TCP threads.
In some situations TCP threads may become frozen. This creates the possibility that Asterisk could segfault if they become unfrozen after chan_sip has been dlclose'd. This reorders the unload_module process to allow abort if threads do not exit within 5 seconds. High level order as follows: 1) Unregister from the core to stop new requests. 2) Signal threads to stop 3) Clear config based tables (but do not free the table itself). 4) Verify that threads have shutdown, cancel unload if not. 5) Clean all remaining resources. ASTERISK-26586 Change-Id: Ie23692041d838fbd35ece61868f4c640960ff882
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c54
1 files changed, 27 insertions, 27 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index f8ae5e522..d62a811a1 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1774,7 +1774,7 @@ static void destroy_escs(void)
{
int i;
for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
- ao2_cleanup(event_state_compositors[i].compositor);
+ ao2_replace(event_state_compositors[i].compositor, NULL);
}
}
@@ -35273,6 +35273,8 @@ static int unload_module(void)
struct ao2_iterator i;
struct timeval start;
+ ast_sched_dump(sched);
+
ast_sip_api_provider_unregister();
if (sip_cfg.websocket_enabled) {
@@ -35282,12 +35284,11 @@ static int unload_module(void)
network_change_stasis_unsubscribe();
acl_change_event_stasis_unsubscribe();
- ast_sched_dump(sched);
-
/* First, take us out of the channel type list */
ast_channel_unregister(&sip_tech);
-
ast_msg_tech_unregister(&sip_msg_tech);
+ ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
+ ast_cc_agent_unregister(&sip_cc_agent_callbacks);
/* Unregister dial plan functions */
ast_custom_function_unregister(&sippeer_function);
@@ -35351,8 +35352,6 @@ static int unload_module(void)
}
ao2_iterator_destroy(&i);
- unlink_all_peers_from_tables();
-
ast_mutex_lock(&monlock);
if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
pthread_t th = monitor_thread;
@@ -35366,7 +35365,12 @@ static int unload_module(void)
ast_mutex_unlock(&monlock);
}
+ /* Clear containers */
+ unlink_all_peers_from_tables();
cleanup_all_regs();
+ sip_epa_unregister_all();
+ destroy_escs();
+ clear_sip_domains();
{
struct ao2_iterator iter;
@@ -35395,6 +35399,23 @@ static int unload_module(void)
*/
ast_sched_runq(sched);
+ /*
+ * Wait awhile for the TCP/TLS thread container to become empty.
+ *
+ * XXX This is a hack, but the worker threads cannot be created
+ * joinable. They can die on their own and remove themselves
+ * from the container thus resulting in a huge memory leak.
+ */
+ start = ast_tvnow();
+ while (ao2_container_count(threadt) && (ast_tvdiff_sec(ast_tvnow(), start) < 5)) {
+ sched_yield();
+ }
+ if (ao2_container_count(threadt)) {
+ ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
+
+ return -1;
+ }
+
/* Free memory for local network address mask */
ast_free_ha(localaddr);
@@ -35405,30 +35426,12 @@ static int unload_module(void)
}
ast_mutex_unlock(&authl_lock);
- sip_epa_unregister_all();
- destroy_escs();
-
ast_free(default_tls_cfg.certfile);
ast_free(default_tls_cfg.pvtfile);
ast_free(default_tls_cfg.cipher);
ast_free(default_tls_cfg.cafile);
ast_free(default_tls_cfg.capath);
- /*
- * Wait awhile for the TCP/TLS thread container to become empty.
- *
- * XXX This is a hack, but the worker threads cannot be created
- * joinable. They can die on their own and remove themselves
- * from the container thus resulting in a huge memory leak.
- */
- start = ast_tvnow();
- while (ao2_container_count(threadt) && (ast_tvdiff_sec(ast_tvnow(), start) < 5)) {
- sched_yield();
- }
- if (ao2_container_count(threadt)) {
- ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
- }
-
ao2_cleanup(registry_list);
ao2_cleanup(subscription_mwi_list);
@@ -35442,7 +35445,6 @@ static int unload_module(void)
ao2_t_cleanup(threadt, "unref the thread table");
ao2_t_cleanup(sip_monitor_instances, "unref the sip_monitor_instances table");
- clear_sip_domains();
sip_cfg.contact_acl = ast_free_acl_list(sip_cfg.contact_acl);
if (sipsock_read_id) {
ast_io_remove(io, sipsock_read_id);
@@ -35455,8 +35457,6 @@ static int unload_module(void)
ast_context_destroy_by_name(used_context, "SIP");
ast_unload_realtime("sipregs");
ast_unload_realtime("sippeers");
- ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
- ast_cc_agent_unregister(&sip_cc_agent_callbacks);
sip_reqresp_parser_exit();
sip_unregister_tests();