[asterisk-commits] trunk r12136 - /trunk/channels/chan_phone.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Mar 6 14:16:26 MST 2006
Author: tilghman
Date: Mon Mar 6 15:16:25 2006
New Revision: 12136
URL: http://svn.digium.com/view/asterisk?rev=12136&view=rev
Log:
Bug 6195 - Deadlock solution by Matti
Modified:
trunk/channels/chan_phone.c
Modified: trunk/channels/chan_phone.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_phone.c?rev=12136&r1=12135&r2=12136&view=diff
==============================================================================
--- trunk/channels/chan_phone.c (original)
+++ trunk/channels/chan_phone.c Mon Mar 6 15:16:25 2006
@@ -36,6 +36,7 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <signal.h>
#include <linux/telephony.h>
/* Still use some IXJ specific stuff */
#include <linux/version.h>
@@ -107,6 +108,9 @@
/* Protect the monitoring thread, so only one process can kill or start it, and not
when it's doing something critical. */
AST_MUTEX_DEFINE_STATIC(monlock);
+
+/* Boolean value whether the monitoring thread shall continue. */
+static unsigned int monitor;
/* This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
@@ -990,22 +994,12 @@
int dotone;
/* This thread monitors all the frame relay interfaces which are not yet in use
(and thus do not have a separate thread) indefinitely */
- /* From here on out, we die whenever asked */
- if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
- ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
- return NULL;
- }
- for(;;) {
+ while (monitor) {
/* Don't let anybody kill us right away. Nobody should lock the interface list
and wait for the monitor list, but the other way around is okay. */
- if (ast_mutex_lock(&monlock)) {
- ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
- return NULL;
- }
/* Lock the interface list */
if (ast_mutex_lock(&iflock)) {
ast_log(LOG_ERROR, "Unable to grab interface lock\n");
- ast_mutex_unlock(&monlock);
return NULL;
}
/* Build the stuff we're going to select on, that is the socket of every
@@ -1015,7 +1009,7 @@
FD_ZERO(&efds);
i = iflist;
dotone = 0;
- while(i) {
+ while (i) {
if (FD_ISSET(i->fd, &rfds))
ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
if (!i->owner) {
@@ -1041,9 +1035,6 @@
/* Okay, now that we know what to do, release the interface lock */
ast_mutex_unlock(&iflock);
- /* And from now on, we're okay to be killed, so release the monitor lock as well */
- ast_mutex_unlock(&monlock);
-
/* Wait indefinitely for something to happen */
if (dotone) {
/* If we're ready to recycle the time, set it to 30 ms */
@@ -1061,7 +1052,7 @@
}
/* Okay, select has finished. Let's see what happened. */
if (res < 0) {
- ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
+ ast_log(LOG_DEBUG, "select return %d: %s\n", res, strerror(errno));
continue;
}
/* If there are no fd's changed, just continue, it's probably time
@@ -1092,7 +1083,6 @@
}
ast_mutex_unlock(&iflock);
}
- /* Never reached */
return NULL;
}
@@ -1113,16 +1103,17 @@
}
if (monitor_thread != AST_PTHREADT_NULL) {
if (ast_mutex_lock(&iflock)) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Unable to lock the interface list\n");
- return -1;
- }
- pthread_cancel(monitor_thread);
-#if 0
+ ast_mutex_unlock(&monlock);
+ ast_log(LOG_WARNING, "Unable to lock the interface list\n");
+ return -1;
+ }
+ monitor = 0;
+ while (pthread_kill(monitor_thread, SIGURG) == 0)
+ sched_yield();
pthread_join(monitor_thread, NULL);
-#endif
ast_mutex_unlock(&iflock);
}
+ monitor = 1;
/* Start a new monitor */
if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
@@ -1278,7 +1269,9 @@
}
if (!ast_mutex_lock(&monlock)) {
if (monitor_thread > AST_PTHREADT_NULL) {
- pthread_cancel(monitor_thread);
+ monitor = 0;
+ while (pthread_kill(monitor_thread, SIGURG) == 0)
+ sched_yield();
pthread_join(monitor_thread, NULL);
}
monitor_thread = AST_PTHREADT_STOP;
More information about the asterisk-commits
mailing list