[svn-commits] rmudgett: branch 11 r432526 - /branches/11/channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Mar 6 13:17:52 CST 2015


Author: rmudgett
Date: Fri Mar  6 13:17:45 2015
New Revision: 432526

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=432526
Log:
chan_sip: Fix realtime locking inversion when poking a just built peer.

When a realtime peer is built it can cause a locking inversion when the
just built peer is poked.  If the CLI command "sip show channels" is
periodically executed then a deadlock can happen because of the locking
inversion.

* Push the peer poke off onto the scheduler thread to avoid the locking
inversion of the just built realtime peer.

AST-1540
ASTERISK-24838 #close
Reported by: Richard Mudgett

Review: https://reviewboard.asterisk.org/r/4454/

Modified:
    branches/11/channels/chan_sip.c

Modified: branches/11/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_sip.c?view=diff&rev=432526&r1=432525&r2=432526
==============================================================================
--- branches/11/channels/chan_sip.c (original)
+++ branches/11/channels/chan_sip.c Fri Mar  6 13:17:45 2015
@@ -15823,6 +15823,17 @@
 	return 0;
 }
 
+static int sip_poke_peer_now(const void *data)
+{
+	struct sip_peer *peer = (struct sip_peer *) data;
+
+	peer->pokeexpire = -1;
+	sip_poke_peer(peer, 0);
+	sip_unref_peer(peer, "removing poke peer ref");
+
+	return 0;
+}
+
 /*! \brief Get registration details from Asterisk DB */
 static void reg_source_db(struct sip_peer *peer)
 {
@@ -20413,24 +20424,33 @@
 static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct ast_str *cbuf;
-	struct ast_cb_names cbnames = {9, { "retrans_pkt",
-                                        "__sip_autodestruct",
-                                        "expire_register",
-                                        "auto_congest",
-                                        "sip_reg_timeout",
-                                        "sip_poke_peer_s",
-                                        "sip_poke_noanswer",
-                                        "sip_reregister",
-                                        "sip_reinvite_retry"},
-								   { retrans_pkt,
-                                     __sip_autodestruct,
-                                     expire_register,
-                                     auto_congest,
-                                     sip_reg_timeout,
-                                     sip_poke_peer_s,
-                                     sip_poke_noanswer,
-                                     sip_reregister,
-                                     sip_reinvite_retry}};
+	struct ast_cb_names cbnames = {
+		10,
+		{
+			"retrans_pkt",
+			"__sip_autodestruct",
+			"expire_register",
+			"auto_congest",
+			"sip_reg_timeout",
+			"sip_poke_peer_s",
+			"sip_poke_peer_now",
+			"sip_poke_noanswer",
+			"sip_reregister",
+			"sip_reinvite_retry"
+		},
+		{
+			retrans_pkt,
+			__sip_autodestruct,
+			expire_register,
+			auto_congest,
+			sip_reg_timeout,
+			sip_poke_peer_s,
+			sip_poke_peer_now,
+			sip_poke_noanswer,
+			sip_reregister,
+			sip_reinvite_retry
+		}
+	};
 	
 	switch (cmd) {
 	case CLI_INIT:
@@ -31357,7 +31377,17 @@
 
 		/* Startup regular pokes */
 		if (!devstate_only && enablepoke) {
-			sip_poke_peer(peer, 0);
+			/*
+			 * We cannot poke the peer now in this thread without
+			 * a lock inversion so pass it off to the scheduler
+			 * thread.
+			 */
+			AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
+				0, /* Poke the peer ASAP */
+				sip_poke_peer_now, peer,
+				sip_unref_peer(_data, "removing poke peer ref"),
+				sip_unref_peer(peer, "removing poke peer ref"),
+				sip_ref_peer(peer, "adding poke peer ref"));
 		}
 	}
 




More information about the svn-commits mailing list