[asterisk-commits] wedhorn: branch wedhorn/readq-locking r252359 - in /team/wedhorn/readq-lockin...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Mar 14 16:41:07 CDT 2010


Author: wedhorn
Date: Sun Mar 14 16:41:02 2010
New Revision: 252359

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=252359
Log:
Merge old patch into current trunk.

Modified:
    team/wedhorn/readq-locking/channels/chan_dahdi.c
    team/wedhorn/readq-locking/channels/chan_iax2.c
    team/wedhorn/readq-locking/channels/chan_sip.c
    team/wedhorn/readq-locking/include/asterisk/channel.h
    team/wedhorn/readq-locking/main/channel.c

Modified: team/wedhorn/readq-locking/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/channels/chan_dahdi.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/channels/chan_dahdi.c (original)
+++ team/wedhorn/readq-locking/channels/chan_dahdi.c Sun Mar 14 16:41:02 2010
@@ -2981,58 +2981,16 @@
 
 static void wakeup_sub(struct dahdi_pvt *p, int a)
 {
-	for (;;) {
-		if (p->subs[a].owner) {
-			if (ast_channel_trylock(p->subs[a].owner)) {
-				DEADLOCK_AVOIDANCE(&p->lock);
-			} else {
-				ast_queue_frame(p->subs[a].owner, &ast_null_frame);
-				ast_channel_unlock(p->subs[a].owner);
-				break;
-			}
-		} else
-			break;
+	if (p->subs[a].owner) {
+		ast_queue_frame(p->subs[a].owner, &ast_null_frame);
 	}
 }
 
 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *data)
 {
-#ifdef HAVE_SS7
-	struct dahdi_ss7 *ss7 = (struct dahdi_ss7*) data;
-
-	if (data) {
-		switch (p->sig) {
-		case SIG_SS7:
-			ast_mutex_unlock(&ss7->lock);
-			break;
-		default:
-			break;
-		}
-	}
-#endif
-	for (;;) {
-		if (p->owner) {
-			if (ast_channel_trylock(p->owner)) {
-				DEADLOCK_AVOIDANCE(&p->lock);
-			} else {
-				ast_queue_frame(p->owner, f);
-				ast_channel_unlock(p->owner);
-				break;
-			}
-		} else
-			break;
-	}
-#if defined(HAVE_SS7)
-	if (data) {
-		switch (p->sig) {
-		case SIG_SS7:
-			ast_mutex_lock(&ss7->lock);
-			break;
-		default:
-			break;
-		}
-	}
-#endif
+	if (p->owner) {
+		ast_queue_frame(p->owner, f);
+	}
 }
 
 static void handle_clear_alarms(struct dahdi_pvt *p)

Modified: team/wedhorn/readq-locking/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/channels/chan_iax2.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/channels/chan_iax2.c (original)
+++ team/wedhorn/readq-locking/channels/chan_iax2.c Sun Mar 14 16:41:02 2010
@@ -2807,27 +2807,15 @@
 /*!
  * \brief Queue a frame to a call's owning asterisk channel
  *
- * \pre This function assumes that iaxsl[callno] is locked when called.
+ * \pre This function assumes that iaxsl[callno] is locked when called. No longer applicable.
  *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
+ * \note IMPORTANT NOTE!!! Behaviour changed, iaxs[callno] will exist when this
+ * function ends assuming lock was held before this was called.
  */
 static int iax2_queue_frame(int callno, struct ast_frame *f)
 {
-	for (;;) {
-		if (iaxs[callno] && iaxs[callno]->owner) {
-			if (ast_channel_trylock(iaxs[callno]->owner)) {
-				/* Avoid deadlock by pausing and trying again */
-				DEADLOCK_AVOIDANCE(&iaxsl[callno]);
-			} else {
-				ast_queue_frame(iaxs[callno]->owner, f);
-				ast_channel_unlock(iaxs[callno]->owner);
-				break;
-			}
-		} else
-			break;
+	if (iaxs[callno] && iaxs[callno]->owner) {
+		ast_queue_frame(iaxs[callno]->owner, f);
 	}
 	return 0;
 }
@@ -2849,6 +2837,8 @@
 {
 	for (;;) {
 		if (iaxs[callno] && iaxs[callno]->owner) {
+			/* XXX Locking only required to set chan->_softhangup, not to queue frame */
+			/* wedhorn: planning on changing _softhangup to atomic at which stage we can remove this locking */
 			if (ast_channel_trylock(iaxs[callno]->owner)) {
 				/* Avoid deadlock by pausing and trying again */
 				DEADLOCK_AVOIDANCE(&iaxsl[callno]);
@@ -2869,28 +2859,16 @@
  * This function queues a control frame on the owner of the IAX2 pvt struct that
  * is active for the given call number.
  *
- * \pre Assumes lock for callno is already held.
+ * \pre Assumes lock for callno is already held. No longer applicable.
  *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
+ * \note IMPORTANT NOTE!!! Behaviour changed, iaxs[callno] will exist when this
+ * function ends assuming lock was held before this was called.
  */
 static int iax2_queue_control_data(int callno, 
 	enum ast_control_frame_type control, const void *data, size_t datalen)
 {
-	for (;;) {
-		if (iaxs[callno] && iaxs[callno]->owner) {
-			if (ast_channel_trylock(iaxs[callno]->owner)) {
-				/* Avoid deadlock by pausing and trying again */
-				DEADLOCK_AVOIDANCE(&iaxsl[callno]);
-			} else {
-				ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
-				ast_channel_unlock(iaxs[callno]->owner);
-				break;
-			}
-		} else
-			break;
+	if (iaxs[callno] && iaxs[callno]->owner) {
+		ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
 	}
 	return 0;
 }

Modified: team/wedhorn/readq-locking/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/channels/chan_sip.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/channels/chan_sip.c (original)
+++ team/wedhorn/readq-locking/channels/chan_sip.c Sun Mar 14 16:41:02 2010
@@ -4104,12 +4104,8 @@
 	sip_pvt_lock(p);
 	p->initid = -1;	/* event gone, will not be rescheduled */
 	if (p->owner) {
-		/* XXX fails on possible deadlock */
-		if (!ast_channel_trylock(p->owner)) {
-			append_history(p, "Cong", "Auto-congesting (timer)");
-			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-			ast_channel_unlock(p->owner);
-		}
+		append_history(p, "Cong", "Auto-congesting (timer)");
+		ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
 
 		/* Give the channel a chance to act before we proceed with destruction */
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);

Modified: team/wedhorn/readq-locking/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/include/asterisk/channel.h?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/include/asterisk/channel.h (original)
+++ team/wedhorn/readq-locking/include/asterisk/channel.h Sun Mar 14 16:41:02 2010
@@ -712,7 +712,7 @@
 	struct varshead varshead;			/*!< A linked list for channel variables. See \ref AstChanVar */
 	ast_group_t callgroup;				/*!< Call group for call pickups */
 	ast_group_t pickupgroup;			/*!< Pickup group - which calls groups can be picked up? */
-	AST_LIST_HEAD_NOLOCK(, ast_frame) readq;
+	AST_LIST_HEAD(, ast_frame) readq;
 	AST_LIST_ENTRY(ast_channel) chan_list;		/*!< For easy linking */
 	struct ast_jb jb;				/*!< The jitterbuffer state */
 	struct timeval dtmf_tv;				/*!< The time that an in process digit began, or the last digit ended */

Modified: team/wedhorn/readq-locking/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/main/channel.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/main/channel.c (original)
+++ team/wedhorn/readq-locking/main/channel.c Sun Mar 14 16:41:02 2010
@@ -963,6 +963,8 @@
 	headp = &tmp->varshead;
 	AST_LIST_HEAD_INIT_NOLOCK(headp);
 	
+	AST_LIST_HEAD_INIT(&tmp->readq);
+	
 	AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
 
 	AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans);
@@ -1071,13 +1073,13 @@
 	unsigned int queued_voice_frames = 0;
 	AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
 
-	ast_channel_lock(chan);
+	AST_LIST_LOCK(&chan->readq);
 
 	/* See if the last frame on the queue is a hangup, if so don't queue anything */
 	if ((cur = AST_LIST_LAST(&chan->readq)) &&
 	    (cur->frametype == AST_FRAME_CONTROL) &&
 	    (cur->subclass.integer == AST_CONTROL_HANGUP)) {
-		ast_channel_unlock(chan);
+		AST_LIST_UNLOCK(&chan->readq);
 		return 0;
 	}
 
@@ -1086,7 +1088,7 @@
 	for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
 		if (!(f = ast_frdup(cur))) {
 			ast_frfree(AST_LIST_FIRST(&frames));
-			ast_channel_unlock(chan);
+			AST_LIST_UNLOCK(&chan->readq);
 			return -1;
 		}
 
@@ -1144,7 +1146,7 @@
 		pthread_kill(chan->blocker, SIGURG);
 	}
 
-	ast_channel_unlock(chan);
+	AST_LIST_UNLOCK(&chan->readq);
 
 	return 0;
 }
@@ -1904,8 +1906,10 @@
 	}
 	close(chan->epfd);
 #endif
+	AST_LIST_LOCK(&chan->readq);
 	while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
 		ast_frfree(f);
+	AST_LIST_UNLOCK(&chan->readq);
 	
 	/* loop over the variables list, freeing all data and deleting list items */
 	/* no need to lock the list, as the channel is already locked */
@@ -3124,6 +3128,8 @@
 	 * point at the end (there are only two exceptions to this).
 	 */
 
+	AST_LIST_LOCK(&chan->readq);
+
 	if (chan->masq) {
 		if (ast_do_masquerade(chan))
 			ast_log(LOG_WARNING, "Failed to perform masquerade\n");
@@ -3194,11 +3200,13 @@
 				int (*func)(const void *) = chan->timingfunc;
 				void *data = chan->timingdata;
 				chan->fdno = -1;
+				AST_LIST_UNLOCK(&chan->readq);
 				ast_channel_unlock(chan);
 				func(data);
 			} else {
 				ast_timer_set_rate(chan->timer, 0);
 				chan->fdno = -1;
+				AST_LIST_UNLOCK(&chan->readq);
 				ast_channel_unlock(chan);
 			}
 
@@ -3564,6 +3572,7 @@
 	if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
 		chan->generator->digit(chan, f->subclass.integer);
 
+	AST_LIST_UNLOCK(&chan->readq);
 	ast_channel_unlock(chan);
 	return f;
 }
@@ -5289,6 +5298,8 @@
 		AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
 		AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
 
+		AST_LIST_LOCK(&original->readq);
+
 		AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
 		AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
 
@@ -5302,6 +5313,7 @@
 				}
 			}
 		}
+		AST_LIST_UNLOCK(&original->readq);
 	}
 
 	/* Swap the raw formats */




More information about the asterisk-commits mailing list