aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_iax2.c
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-11-04 23:03:00 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-11-04 23:03:00 +0000
commitd6530734b8fc799ffb1ce764716bc5d02b86afde (patch)
treecc17fe86e28c6faeca8c1210b0ce50a36adb6709 /channels/chan_iax2.c
parentf4647bcf73681bc5f5d4cf81838e9cb34488e717 (diff)
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: http://svn.digium.com/svn/asterisk/trunk@154428 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r--channels/chan_iax2.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 9f3e6185f..09d2dff27 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);