diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-03-23 23:11:09 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-03-23 23:11:09 +0000 |
commit | 402c85f9c8836964840d929e491a1b3bd37911b5 (patch) | |
tree | 4d69783aea33836fb2e8dcb826e8789dacc8e2f0 | |
parent | 4a9bc54bbefb857e0b6d456974bfceab974c76da (diff) |
commit file's work to convert iax2 multithreading to use pthread conditions instead of signals (with some modifications)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@14570 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | channels/chan_iax2.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index b312d8599..042dbf4b1 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -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); } |