From 4a06abfee4577fc4bda9f4862392e85cdea97d5f Mon Sep 17 00:00:00 2001
From: Alec L Davis <sivad.a@paradise.net.nz>
Date: Fri, 12 Apr 2013 08:16:15 +0000
Subject: [PATCH] IAX2, prevent network thread starting before all helper
 threads are ready

On startup, it's possible for a frame to arrive before the processing threads were ready.

In iax2_process_thread() the first pass through falls into ast_cond_wait, should a frame arrive
before we are at ast_cond_wait, the signal will be ignored.
The result iax2_process_thread stays at ast_cond_wait forever, with deferred frames being queued.

Fix: When creating initial idle iax2_process_threads, wait for init_cond to be signalled
after each thread is started.

(issue ASTERISK-18827)
Reported by: alecdavis
Tested by: alecdavis
alecdavis (license 585)

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

Merged revisions 385402 from http://svn.asterisk.org/svn/asterisk/branches/1.8


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@385403 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/chan_iax2.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 13d25b7b05..538b56ad54 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -12402,16 +12402,26 @@ static int start_network_thread(void)
 			ast_cond_init(&thread->cond, NULL);
 			ast_mutex_init(&thread->init_lock);
 			ast_cond_init(&thread->init_cond, NULL);
+
+			ast_mutex_lock(&thread->init_lock);
+
 			if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
 				ast_log(LOG_WARNING, "Failed to create new thread!\n");
 				ast_mutex_destroy(&thread->lock);
 				ast_cond_destroy(&thread->cond);
+				ast_mutex_unlock(&thread->init_lock);
 				ast_mutex_destroy(&thread->init_lock);
 				ast_cond_destroy(&thread->init_cond);
 				ast_free(thread);
 				thread = NULL;
 				continue;
 			}
+			/* Wait for the thread to be ready */
+			ast_cond_wait(&thread->init_cond, &thread->init_lock);
+
+			/* Done with init_lock */
+			ast_mutex_unlock(&thread->init_lock);
+
 			AST_LIST_LOCK(&idle_list);
 			AST_LIST_INSERT_TAIL(&idle_list, thread, list);
 			AST_LIST_UNLOCK(&idle_list);
-- 
GitLab