]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
commit file's work to convert iax2 multithreading to use pthread conditions instead...
authorKevin P. Fleming <kpfleming@digium.com>
Thu, 23 Mar 2006 23:11:09 +0000 (23:11 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Thu, 23 Mar 2006 23:11:09 +0000 (23:11 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@14570 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c

index b312d85994c2ba829b64a551b2aa857602a3da15..042dbf4b17545ce53e5cc6024cce663caa7b8681 100644 (file)
@@ -240,6 +240,9 @@ static struct ast_flags globalflags = { 0 };
 
 static pthread_t netthreadid = AST_PTHREADT_NULL;
 static pthread_t schedthreadid = AST_PTHREADT_NULL;
+AST_MUTEX_DEFINE_STATIC(sched_lock);
+static int sched_halt = 0;
+static ast_cond_t sched_cond;
 
 enum {
        IAX_STATE_STARTED =             (1 << 0),
@@ -696,6 +699,8 @@ struct iax2_thread {
        int iores;
        int iofd;
        time_t checktime;
+       ast_mutex_t lock;
+       ast_cond_t cond;
 };
 
 struct iax2_thread_list {
@@ -704,6 +709,13 @@ struct iax2_thread_list {
 
 static struct iax2_thread_list idlelist, activelist;
 
+static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
+{
+       ast_mutex_lock(lock);
+       ast_cond_signal(cond);
+       ast_mutex_unlock(lock);
+}
+
 static void iax_debug_output(const char *data)
 {
        if (iaxdebug)
@@ -836,7 +848,7 @@ static int __schedule_action(void (*func)(void *data), void *data, const char *f
 #ifdef DEBUG_SCHED_MULTITHREAD
                ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
 #endif
-               pthread_kill(thread->threadid, SIGURG);
+               signal_condition(&thread->lock, &thread->cond);
                return 0;
        }
        time(&t);
@@ -2283,7 +2295,9 @@ static void update_jbsched(struct chan_iax2_pvt *pvt) {
     }
 
     pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt);
-       pthread_kill(schedthreadid, SIGURG);
+
+    /* Signal scheduler thread */
+    signal_condition(&sched_lock, &sched_cond);
 }
 
 static void __get_from_jb(void *p) 
@@ -2617,7 +2631,7 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
                if (option_debug && iaxdebug)
                        ast_log(LOG_DEBUG, "schedule_delivery: Scheduling delivery in %d ms\n", delay);
                fr->retrans = ast_sched_add(sched, delay, do_deliver, fr);
-               pthread_kill(schedthreadid, SIGURG);
+               signal_condition(&sched_lock, &sched_cond);
        }
 #endif
        if (tsout)
@@ -2653,7 +2667,7 @@ static int iax2_transmit(struct iax_frame *fr)
        ast_mutex_unlock(&iaxq.lock);
        /* Wake up the network and scheduler thread */
        pthread_kill(netthreadid, SIGURG);
-       pthread_kill(schedthreadid, SIGURG);
+       signal_condition(&sched_lock, &sched_cond);
        return 0;
 }
 
@@ -6512,7 +6526,7 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 #ifdef DEBUG_SCHED_MULTITHREAD
                ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
 #endif
-               pthread_kill(thread->threadid, SIGURG);
+               signal_condition(&thread->lock, &thread->cond);
        } else {
                time(&t);
                if (t != last_errtime)
@@ -7882,18 +7896,20 @@ retryowner2:
 static void destroy_helper(struct iax2_thread *thread)
 {
        ast_log(LOG_DEBUG, "Destroying helper %d!\n", thread->threadnum);
+       ast_mutex_destroy(&thread->lock);
+       ast_cond_destroy(&thread->cond);
        free(thread);
 }
 
 static void *iax2_process_thread(void *data)
 {
        struct iax2_thread *thread_copy, *thread = data;
-       struct timeval tv;
+
        for(;;) {
-               /* Sleep for up to 1 second */
-               tv.tv_sec = 1;
-               tv.tv_usec = 0;
-               select(0, NULL, NULL, NULL, &tv);
+               /* Wait for something to signal us to be awake */
+               ast_mutex_lock(&thread->lock);
+               ast_cond_wait(&thread->cond, &thread->lock);
+               ast_mutex_unlock(&thread->lock);
                /* Unlink from idlelist / activelist if there*/
                ASTOBJ_CONTAINER_UNLINK(&idlelist, thread);
                ASTOBJ_CONTAINER_UNLINK(&activelist, thread);
@@ -8248,19 +8264,25 @@ static void *sched_thread(void *ignore)
 {
        int count;
        int res;
+       struct timespec ts;
+
        for (;;) {
                res = ast_sched_wait(sched);
                if ((res > 1000) || (res < 0))
                        res = 1000;
-               res = poll(NULL, 0, res);
-               if (res < 0) {
-                       if ((errno != EAGAIN) && (errno != EINTR))
-                               ast_log(LOG_WARNING, "poll failed: %s\n", strerror(errno));
-               }
+               ts.tv_sec = res;
+
+               ast_mutex_lock(&sched_lock);
+               ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
+               if (sched_halt == 1)
+                       break;
+               ast_mutex_unlock(&sched_lock);
+
                count = ast_sched_runq(sched);
                if (count >= 20)
                        ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
        }
+       ast_mutex_unlock(&sched_lock);
        return NULL;
 }
 
@@ -8304,7 +8326,7 @@ static void *network_thread(void *ignore)
                                        /* We need reliable delivery.  Schedule a retransmission */
                                        f->retries++;
                                        f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
-                                       pthread_kill(schedthreadid, SIGURG);
+                                       signal_condition(&sched_lock, &sched_cond);
                                }
                        }
                        f = f->next;
@@ -8336,6 +8358,8 @@ static int start_network_thread(void)
                if (thread) {
                        ASTOBJ_INIT(thread);
                        thread->threadnum = ++threadcount;
+                       ast_mutex_init(&thread->lock);
+                       ast_cond_init(&thread->cond, NULL);
                        if (ast_pthread_create(&thread->threadid, NULL, iax2_process_thread, thread)) {
                                ast_log(LOG_WARNING, "Failed to create new thread!\n");
                                free(thread);
@@ -9862,16 +9886,20 @@ static int __unload_module(void)
        }
        if (schedthreadid != AST_PTHREADT_NULL) {
                pthread_cancel(schedthreadid);
+               ast_mutex_lock(&sched_lock);
+               sched_halt = 1;
+               ast_cond_signal(&sched_cond);
+               ast_mutex_unlock(&sched_lock);
                pthread_join(schedthreadid, NULL);
        }
        while (idlelist.head || activelist.head) {
                ASTOBJ_CONTAINER_TRAVERSE(&idlelist, 1, {
                        iterator->halt = 1;
-                       pthread_kill(iterator->threadid, SIGURG);
+                       signal_condition(&iterator->lock, &iterator->cond);
                });
                ASTOBJ_CONTAINER_TRAVERSE(&activelist, 1, {
                        iterator->halt = 1;
-                       pthread_kill(iterator->threadid, SIGURG);
+                       signal_condition(&iterator->lock, &iterator->cond);
                });
                usleep(100000);
        }