[asterisk-commits] trunk r14570 - /trunk/channels/chan_iax2.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Mar 23 16:11:09 MST 2006


Author: kpfleming
Date: Thu Mar 23 17:11:09 2006
New Revision: 14570

URL: http://svn.digium.com/view/asterisk?rev=14570&view=rev
Log:
commit file's work to convert iax2 multithreading to use pthread conditions instead of signals (with some modifications)

Modified:
    trunk/channels/chan_iax2.c

Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?rev=14570&r1=14569&r2=14570&view=diff
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Thu Mar 23 17:11:09 2006
@@ -240,6 +240,9 @@
 
 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 @@
 	int iores;
 	int iofd;
 	time_t checktime;
+	ast_mutex_t lock;
+	ast_cond_t cond;
 };
 
 struct iax2_thread_list {
@@ -703,6 +708,13 @@
 };
 
 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)
 {
@@ -836,7 +848,7 @@
 #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 @@
     }
 
     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 @@
 		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 @@
 	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 @@
 #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 @@
 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 @@
 {
 	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 @@
 					/* 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 @@
 		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 @@
 	}
 	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);
 	}



More information about the asterisk-commits mailing list