[asterisk-commits] bmd: branch group/newcdr r189919 - /team/group/newcdr/channels/chan_iax2.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 22 11:18:14 CDT 2009


Author: bmd
Date: Wed Apr 22 11:18:10 2009
New Revision: 189919

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=189919
Log:
fix a deadlock with setting hangupsource for iax calls

Modified:
    team/group/newcdr/channels/chan_iax2.c

Modified: team/group/newcdr/channels/chan_iax2.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/newcdr/channels/chan_iax2.c?view=diff&rev=189919&r1=189918&r2=189919
==============================================================================
--- team/group/newcdr/channels/chan_iax2.c (original)
+++ team/group/newcdr/channels/chan_iax2.c Wed Apr 22 11:18:10 2009
@@ -8324,6 +8324,34 @@
 	.read = acf_iaxvar_read,
 	.write = acf_iaxvar_write,
 };
+
+static void set_hangup_source_and_cause(int callno, unsigned char causecode)
+{
+	int locked = 0;
+
+	do {
+		if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
+			DEADLOCK_AVOIDANCE(&iaxsl[callno]);
+		}
+		else {
+			locked = 1;
+		}
+	}
+	while (!locked && iaxs[callno] && iaxs[callno]->owner);
+
+	if (iaxs[callno] && iaxs[callno]->owner) {
+		if (causecode) {
+			iaxs[callno]->owner->hangupcause = causecode;
+		}
+		ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
+		ast_mutex_unlock(&iaxs[callno]->owner->lock);
+	}
+	else if (locked) {
+		ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
+		ast_mutex_unlock(&iaxsl[callno]);
+	}
+}
+
 
 static int socket_process(struct iax2_thread *thread)
 {
@@ -9092,11 +9120,7 @@
 				ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
 				/* Set hangup cause according to remote and hangupsource */
 				if (iaxs[fr->callno]->owner) {
-					struct ast_channel *owner = iaxs[fr->callno]->owner;
-					if (ies.causecode) {
-						owner->hangupcause = ies.causecode;
-					}
-					ast_set_hangupsource(owner, owner->name, 0);
+					set_hangup_source_and_cause(fr->callno, ies.causecode);
 				}
 
 				/* Send ack immediately, before we destroy */
@@ -9106,11 +9130,7 @@
 			case IAX_COMMAND_REJECT:
 				/* Set hangup cause according to remote and hangup source */
 				if (iaxs[fr->callno]->owner) {
-					struct ast_channel *owner = iaxs[fr->callno]->owner;
-					if (ies.causecode) {
-						owner->hangupcause = ies.causecode;
-					}
-					ast_set_hangupsource(owner, owner->name, 0);
+					set_hangup_source_and_cause(fr->callno, ies.causecode);
 				}
 
 				if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {




More information about the asterisk-commits mailing list