Switch to using a thread condition to signal that a child thread is ready for
authorTilghman Lesher <tilghman@meg.abyt.es>
Tue, 4 Nov 2008 23:03:00 +0000 (23:03 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Tue, 4 Nov 2008 23:03:00 +0000 (23:03 +0000)
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

index 9f3e618..09d2dff 100644 (file)
@@ -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);