[svn-commits] mnicholson: branch mnicholson/chan-mobile-refactor r810 - /team/mnicholson/ch...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Mar 16 17:46:21 CDT 2009


Author: mnicholson
Date: Mon Mar 16 17:46:17 2009
New Revision: 810

URL: http://svn.digium.com/svn-view/asterisk-addons?view=rev&rev=810
Log:
Added deadlock avoidance when calling ast_queue_* functions.

Modified:
    team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c

Modified: team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c
URL: http://svn.digium.com/svn-view/asterisk-addons/team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c?view=diff&rev=810&r1=809&r2=810
==============================================================================
--- team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c (original)
+++ team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c Mon Mar 16 17:46:17 2009
@@ -218,6 +218,9 @@
 
 static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen);
 
+static int mbl_queue_control(struct mbl_pvt *pvt, enum ast_control_frame_type control);
+static int mbl_queue_hangup(struct mbl_pvt *pvt);
+
 static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel);
 static int rfcomm_write(int rsock, char *buf);
 static int rfcomm_write_full(int rsock, char *buf, size_t count);
@@ -1182,6 +1185,40 @@
 	} else
 		pvt->do_alignment_detection = 0;
 
+}
+
+static int mbl_queue_control(struct mbl_pvt *pvt, enum ast_control_frame_type control)
+{
+	for (;;) {
+		if (pvt->owner) {
+			if (ast_channel_trylock(pvt->owner)) {
+				DEADLOCK_AVOIDANCE(&pvt->lock);
+			} else {
+				ast_queue_control(pvt->owner, control);
+				ast_channel_unlock(pvt->owner);
+				break;
+			}
+		} else
+			break;
+	}
+	return 0;
+}
+
+static int mbl_queue_hangup(struct mbl_pvt *pvt)
+{
+	for (;;) {
+		if (pvt->owner) {
+			if (ast_channel_trylock(pvt->owner)) {
+				DEADLOCK_AVOIDANCE(&pvt->lock);
+			} else {
+				ast_queue_hangup(pvt->owner);
+				ast_channel_unlock(pvt->owner);
+				break;
+			}
+		} else
+			break;
+	}
+	return 0;
 }
 
 /*
@@ -2918,11 +2955,11 @@
 		switch (entry->response_to) {
 		case AT_A:
 			ast_debug(1, "[%s] answer failed\n", pvt->id);
-			ast_queue_hangup(pvt->owner);
+			mbl_queue_hangup(pvt);
 			break;
 		case AT_D:
 			ast_debug(1, "[%s] dial failed\n", pvt->id);
-			ast_queue_control(pvt->owner, AST_CONTROL_CONGESTION);
+			mbl_queue_control(pvt, AST_CONTROL_CONGESTION);
 			break;
 		case AT_CHUP:
 			ast_debug(1, "[%s] error sending hangup, disconnecting\n", pvt->id);
@@ -2969,7 +3006,7 @@
 		switch (i) {
 		case HFP_CIND_CALL_NONE:
 			if (pvt->owner) {
-				if (ast_queue_hangup(pvt->owner)) {
+				if (mbl_queue_hangup(pvt)) {
 					ast_log(LOG_ERROR, "[%s] error queueing hangup, disconnectiong...\n", pvt->id);
 					return -1;
 				}
@@ -2982,13 +3019,13 @@
 		case HFP_CIND_CALL_ACTIVE:
 			if (pvt->outgoing) {
 				ast_debug(1, "[%s] remote end answered\n", pvt->id);
-				ast_queue_control(pvt->owner, AST_CONTROL_ANSWER);
+				mbl_queue_control(pvt, AST_CONTROL_ANSWER);
 			} else if (pvt->incoming && pvt->sent_answer) {
 				ast_setstate(pvt->owner, AST_STATE_UP);
 			} else if (pvt->incoming) {
 				/* user answered from handset, disconnecting */
 				ast_verb(3, "[%s] user answered bluetooth device from handset, disconnecting\n", pvt->id);
-				ast_queue_hangup(pvt->owner);
+				mbl_queue_hangup(pvt);
 				return -1;
 			}
 			break;
@@ -3000,7 +3037,7 @@
 		case HFP_CIND_CALLSETUP_NONE:
 			if (pvt->hfp->cind_state[pvt->hfp->cind_map.call] != HFP_CIND_CALL_ACTIVE) {
 				if (pvt->owner) {
-					if (ast_queue_hangup(pvt->owner)) {
+					if (mbl_queue_hangup(pvt)) {
 						ast_log(LOG_ERROR, "[%s] error queueing hangup, disconnectiong...\n", pvt->id);
 						return -1;
 					}
@@ -3027,7 +3064,7 @@
 		case HFP_CIND_CALLSETUP_ALERTING:
 			if (pvt->outgoing) {
 				ast_debug(1, "[%s] remote alerting\n", pvt->id);
-				ast_queue_control(pvt->owner, AST_CONTROL_RINGING);
+				mbl_queue_control(pvt, AST_CONTROL_RINGING);
 			}
 			break;
 		}
@@ -3305,7 +3342,7 @@
 	if (pvt->owner) {
 		ast_debug(1, "[%s] device disconnected, hanging up owner\n", pvt->id);
 		pvt->needchup = 0;
-		ast_queue_hangup(pvt->owner);
+		mbl_queue_hangup(pvt);
 	}
 
 	close(pvt->rfcomm_socket);
@@ -3362,7 +3399,7 @@
 			switch (pvt->state) {
 			case MBL_STATE_RING2:
 				if (at_msg == AT_CKPD) {
-					ast_queue_control(pvt->owner, AST_CONTROL_ANSWER);
+					mbl_queue_control(pvt, AST_CONTROL_ANSWER);
 					pvt->state = MBL_STATE_INCOMING;
 					if (hsp_send_vgs(pvt->rfcomm_socket, 13) || hsp_send_vgm(pvt->rfcomm_socket, 13)) {
 						ast_debug(1, "[%s] error sending VGS/VGM\n", pvt->id);
@@ -3372,7 +3409,7 @@
 				break;
 			case MBL_STATE_INCOMING:
 				if (at_msg == AT_CKPD) {
-					ast_queue_control(pvt->owner, AST_CONTROL_HANGUP);
+					mbl_queue_control(pvt, AST_CONTROL_HANGUP);
 				}
 				break;
 			default:
@@ -3399,15 +3436,15 @@
 				if (pvt->sco_socket > -1) {
 					if (!ast_io_add(io, pvt->sco_socket, sco_read, AST_IO_IN, pvt)) {
 						ast_log(LOG_ERROR, "error monitoring new audio connection for device %s\n", pvt->id);
-						ast_queue_control(pvt->owner, AST_CONTROL_HANGUP);
+						mbl_queue_control(pvt, AST_CONTROL_HANGUP);
 						close(pvt->sco_socket);
 						goto e_cleanup;
 					}
 					ast_setstate(pvt->owner, AST_STATE_RINGING);
-					ast_queue_control(pvt->owner, AST_CONTROL_RINGING);
+					mbl_queue_control(pvt, AST_CONTROL_RINGING);
 					pvt->state = MBL_STATE_RING2;
 				} else {
-					ast_queue_control(pvt->owner, AST_CONTROL_HANGUP);
+					mbl_queue_control(pvt, AST_CONTROL_HANGUP);
 				}
 			} else if (pvt->state == MBL_STATE_RING2) {
 				if (hsp_send_ring(pvt->rfcomm_socket)) {
@@ -3426,7 +3463,7 @@
 	ast_mutex_lock(&pvt->lock);
 	if (pvt->owner) {
 		ast_debug(1, "[%s] device disconnected, hanging up owner\n", pvt->id);
-		ast_queue_hangup(pvt->owner);
+		mbl_queue_hangup(pvt);
 	}
 
 




More information about the svn-commits mailing list