[asterisk-commits] dvossel: branch dvossel/masq_locking_order_trunk r222350 - in /team/dvossel/m...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 6 15:33:20 CDT 2009


Author: dvossel
Date: Tue Oct  6 15:33:15 2009
New Revision: 222350

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=222350
Log:
adds channel ref during sip transfers, adds a function note to channel.h


Modified:
    team/dvossel/masq_locking_order_trunk/channels/chan_sip.c
    team/dvossel/masq_locking_order_trunk/include/asterisk/channel.h
    team/dvossel/masq_locking_order_trunk/main/channel.c

Modified: team/dvossel/masq_locking_order_trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/masq_locking_order_trunk/channels/chan_sip.c?view=diff&rev=222350&r1=222349&r2=222350
==============================================================================
--- team/dvossel/masq_locking_order_trunk/channels/chan_sip.c (original)
+++ team/dvossel/masq_locking_order_trunk/channels/chan_sip.c Tue Oct  6 15:33:15 2009
@@ -19783,7 +19783,11 @@
 	else
 		ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
 
-	/* C should now be in place of replacecall. all channel locks and pvt locks should be removed before issuing the masq */
+	/* C should now be in place of replacecall. all channel locks and pvt locks should be removed
+	 * before issuing the masq.  Since we are unlocking both the pvt (p) and its owner channel (c)
+	 * it is possible for channel c to be destroyed on us.  To prevent this, we must give c a reference
+	 * before any unlocking takes place and remove it only once we are completely done with it */
+	ast_channel_ref(c);
 	ast_channel_unlock(replacecall);
 	ast_channel_unlock(c);
 	sip_pvt_unlock(p->refer->refer_call);
@@ -19791,7 +19795,6 @@
 	if (ast_do_masquerade(replacecall)) {
 		ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
 	}
-
 	ast_channel_lock(c);
 	if (earlyreplace || oneleggedreplace ) {
 		c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
@@ -19804,11 +19807,11 @@
 
 	/* c and c's tech pvt must be unlocked at this point for ast_hangup */
 	ast_hangup(c);
-
 	/* this indicates to handle_request_do that the owner channel has already been unlocked */
 	*nounlock = 1;
 	/* lock PVT structure again after hangup */
 	sip_pvt_lock(p);
+	ast_channel_unref(c);
 	return 0;
 }
 
@@ -21038,10 +21041,15 @@
 		 * can queue connected line updates where they need to go.
 		 *
 		 * before a masquerade, all channel and pvt locks must be unlocked.  Any recursive
-		 * channel locks held before this function invalidates channel container locking order
+		 * channel locks held before this function invalidates channel container locking order.
+		 * Since we are unlocking both the pvt (transferer) and its owner channel (current.chan1)
+		 * it is possible for current.chan1 to be destroyed in the pbx thread.  To prevent this
+		 * we must give c a reference before any unlocking takes place.
 		 */
+
+		ast_channel_ref(current->chan1);
+		ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/
 		ast_channel_unlock(target.chan1);
-		ast_channel_unlock(current->chan1); /* current.chan1 is p->owner before the masq, it was locked by socket_read()*/
 		*nounlock = 1;  /* we just unlocked the dialog's channel and have no plans of locking it again. */
 		sip_pvt_unlock(targetcall_pvt);
 		sip_pvt_unlock(transferer);
@@ -21061,6 +21069,7 @@
 			 */
 			ast_channel_update_connected_line(target.chan1, &connected_to_target);
 		}
+		ast_channel_unref(current->chan1);
 	}
 
 	/* at this point if the transfer is successful only the transferer pvt should be locked. */

Modified: team/dvossel/masq_locking_order_trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/masq_locking_order_trunk/include/asterisk/channel.h?view=diff&rev=222350&r1=222349&r2=222350
==============================================================================
--- team/dvossel/masq_locking_order_trunk/include/asterisk/channel.h (original)
+++ team/dvossel/masq_locking_order_trunk/include/asterisk/channel.h Tue Oct  6 15:33:15 2009
@@ -1060,6 +1060,11 @@
  * \param newname the name to change to
  *
  * \return nothing
+ *
+ * \note this function must _NEVER_ be used when any channels are locked
+ * regardless if it is the channel who's name is being changed or not because
+ * it invalidates our channel container locking order... lock container first,
+ * then the individual channels, never the other way around.
  */
 void ast_change_name(struct ast_channel *chan, const char *newname);
 

Modified: team/dvossel/masq_locking_order_trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/masq_locking_order_trunk/main/channel.c?view=diff&rev=222350&r1=222349&r2=222350
==============================================================================
--- team/dvossel/masq_locking_order_trunk/main/channel.c (original)
+++ team/dvossel/masq_locking_order_trunk/main/channel.c Tue Oct  6 15:33:15 2009
@@ -4819,10 +4819,6 @@
 	ast_string_field_set(chan, name, newname);
 }
 
-/*! \note this function must _NEVER_ ever ever be used when any channels
- * are locked regardless if it is the channel who's name is being changed
- * or not because it invalidates our channel container locking order...
- * lock container first, then the channels, never the other way around. */
 void ast_change_name(struct ast_channel *chan, const char *newname)
 {
 	/* We must re-link, as the hash value will change here. */




More information about the asterisk-commits mailing list