diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index b312d85994c2ba829b64a551b2aa857602a3da15..042dbf4b17545ce53e5cc6024cce663caa7b8681 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);
 	}