aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-03-23 23:11:09 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-03-23 23:11:09 +0000
commit402c85f9c8836964840d929e491a1b3bd37911b5 (patch)
tree4d69783aea33836fb2e8dcb826e8789dacc8e2f0
parent4a9bc54bbefb857e0b6d456974bfceab974c76da (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.c64
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);
}