From bdb21bef93ce295c7593165a435fede4cf7034e4 Mon Sep 17 00:00:00 2001
From: Tilghman Lesher <tilghman@meg.abyt.es>
Date: Tue, 4 Nov 2008 23:03:00 +0000
Subject: [PATCH] Switch to using a thread condition to signal that a child
 thread is ready for work, rather than a busy wait. (closes issue #13011) 
 Reported by: jpgrayson  Patches:        chan_iax2_find_idle.patch uploaded by
 jpgrayson (license 492)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@154428 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/chan_iax2.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 9f3e6185f3..09d2dff275 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -860,7 +860,8 @@ struct iax2_thread {
 	time_t checktime;
 	ast_mutex_t lock;
 	ast_cond_t cond;
-	unsigned int ready_for_signal:1;
+	ast_mutex_t init_lock;
+	ast_cond_t init_cond;
 	/*! if this thread is processing a full frame,
 	  some information about that frame will be stored
 	  here, so we can avoid dispatching any more full
@@ -1201,6 +1202,9 @@ static struct iax2_thread *find_idle_thread(void)
 	/* Initialize lock and condition */
 	ast_mutex_init(&thread->lock);
 	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);
 
 	/* Create thread and send it on it's way */
 	if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
@@ -1215,8 +1219,10 @@ static struct iax2_thread *find_idle_thread(void)
 	memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
 
 	/* Wait for the thread to be ready before returning it to the caller */
-	while (!thread->ready_for_signal)
-		usleep(1);
+	ast_cond_wait(&thread->init_cond, &thread->init_lock);
+
+	/* Done with init_lock */
+	ast_mutex_unlock(&thread->init_lock);
 
 	return thread;
 }
@@ -9875,6 +9881,8 @@ static void iax2_process_thread_cleanup(void *data)
 	struct iax2_thread *thread = data;
 	ast_mutex_destroy(&thread->lock);
 	ast_cond_destroy(&thread->cond);
+	ast_mutex_destroy(&thread->init_lock);
+	ast_cond_destroy(&thread->init_cond);
 	ast_free(thread);
 	ast_atomic_dec_and_test(&iaxactivethreadcount);
 }
@@ -9885,6 +9893,7 @@ static void *iax2_process_thread(void *data)
 	struct timeval wait;
 	struct timespec ts;
 	int put_into_idle = 0;
+	int first_time = 1;
 
 	ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
 	pthread_cleanup_push(iax2_process_thread_cleanup, data);
@@ -9893,8 +9902,11 @@ static void *iax2_process_thread(void *data)
 		ast_mutex_lock(&thread->lock);
 
 		/* Flag that we're ready to accept signals */
-		thread->ready_for_signal = 1;
-		
+		if (first_time) {
+			signal_condition(&thread->init_lock, &thread->init_cond);
+			first_time = 0;
+		}
+
 		/* Put into idle list if applicable */
 		if (put_into_idle)
 			insert_idle_thread(thread);
-- 
GitLab