[Pkg-voip-commits] r9968 - /asterisk/branches/squeeze/debian/patches/AST-2012-010
maniac-guest at alioth.debian.org
maniac-guest at alioth.debian.org
Wed Sep 19 12:35:28 UTC 2012
Author: maniac-guest
Date: Wed Sep 19 12:35:28 2012
New Revision: 9968
URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=9968
Log:
working on backport AST-2012-010
Modified:
asterisk/branches/squeeze/debian/patches/AST-2012-010
Modified: asterisk/branches/squeeze/debian/patches/AST-2012-010
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/AST-2012-010?rev=9968&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/patches/AST-2012-010 (original)
+++ asterisk/branches/squeeze/debian/patches/AST-2012-010 Wed Sep 19 12:35:28 2012
@@ -12,8 +12,10 @@
Don't use sip_pvt_lock_full or ast_channel_unref functions.
---- a/channels/chan_sip.c
-+++ b/channels/chan_sip.c
+Index: asterisk-1.6.2.9/channels/chan_sip.c
+===================================================================
+--- asterisk-1.6.2.9.orig/channels/chan_sip.c 2012-09-19 12:20:49.000000000 +0200
++++ asterisk-1.6.2.9/channels/chan_sip.c 2012-09-19 14:31:28.000000000 +0200
@@ -1662,6 +1662,7 @@
struct sip_auth *peerauth; /*!< Realm authentication */
int noncecount; /*!< Nonce-count */
@@ -30,7 +32,15 @@
int autokillid; /*!< Auto-kill ID (scheduler) */
int t38id; /*!< T.38 Response ID */
enum transfermodes allowtransfer; /*!< REFER: restriction scheme */
-@@ -4081,7 +4083,7 @@
+@@ -2392,6 +2394,7 @@
+ static int restart_monitor(void);
+ static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer);
+ static struct ast_variable *copy_vars(struct ast_variable *src);
++static struct ast_channel *sip_pvt_lock_full(struct sip_pvt *pvt);
+ /* static int sip_addrcmp(char *name, struct sockaddr_in *sin); Support for peer matching */
+ static int sip_refer_allocate(struct sip_pvt *p);
+ static void ast_quiet_chan(struct ast_channel *chan);
+@@ -4081,7 +4084,7 @@
ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
append_history(p, "ReliableXmit", "timeout");
if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
@@ -39,27 +49,29 @@
pvt_set_needdestroy(p, "autodestruct");
}
}
-@@ -6092,6 +6094,19 @@
- return 0;
+@@ -6093,6 +6096,21 @@
}
+
+static int reinvite_timeout(const void *data)
+{
+ struct sip_pvt *dialog = (struct sip_pvt *) data;
-+ struct ast_channel *owner = sip_pvt_lock(dialog);
++ struct ast_channel *owner = sip_pvt_lock_full(dialog);
+ dialog->reinviteid = -1;
+ check_pendings(dialog);
+ if (owner) {
+ ast_channel_unlock(owner);
++ ao2_ref(owner, -1); //ast_channel_unref(owner);
+ }
+ sip_pvt_unlock(dialog);
+ dialog_unref(dialog, "unref for reinvite timeout");
+ return 0;
+}
-
++
/*! \brief sip_hangup: Hangup SIP call
* Part of PBX interface, called from ast_hangup */
-@@ -6289,8 +6304,16 @@
+ static int sip_hangup(struct ast_channel *ast)
+@@ -6289,8 +6307,16 @@
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);
AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
@@ -77,7 +89,7 @@
}
}
}
-@@ -7338,6 +7361,7 @@
+@@ -7338,6 +7364,7 @@
p->method = intended_method;
p->initid = -1;
p->waitid = -1;
@@ -85,7 +97,80 @@
p->autokillid = -1;
p->request_queue_sched_id = -1;
p->provisional_keepalive_sched_id = -1;
-@@ -10715,7 +10739,7 @@
+@@ -7513,6 +7540,72 @@
+ return found;
+ }
+
++/*! \internal
++ *
++ * \brief Locks both pvt and pvt owner if owner is present.
++ *
++ * \note This function gives a ref to pvt->owner if it is present and locked.
++ * This reference must be decremented after pvt->owner is unlocked.
++ *
++ * \note This function will never give you up,
++ * \note This function will never let you down.
++ * \note This function will run around and desert you.
++ *
++ * \pre pvt is not locked
++ * \post pvt is locked
++ * \post pvt->owner is locked and its reference count is increased (if pvt->owner is not NULL)
++ *
++ * \returns a pointer to the locked and reffed pvt->owner channel if it exists.
++ */
++static struct ast_channel *sip_pvt_lock_full(struct sip_pvt *pvt)
++{
++ struct ast_channel *chan;
++
++ /* Locking is simple when it is done right. If you see a deadlock resulting
++ * in this function, it is not this function's fault, Your problem exists elsewhere.
++ * This function is perfect... seriously. */
++ for (;;) {
++ /* First, get the channel and grab a reference to it */
++ sip_pvt_lock(pvt);
++ chan = pvt->owner;
++ if (chan) {
++ /* The channel can not go away while we hold the pvt lock.
++ * Give the channel a ref so it will not go away after we let
++ * the pvt lock go. */
++ ao2_ref(chan, +1); //ast_channel_ref(chan);
++ } else {
++ /* no channel, return pvt locked */
++ return NULL;
++ }
++
++ /* We had to hold the pvt lock while getting a ref to the owner channel
++ * but now we have to let this lock go in order to preserve proper
++ * locking order when grabbing the channel lock */
++ sip_pvt_unlock(pvt);
++
++ /* Look, no deadlock avoidance, hooray! */
++ ast_channel_lock(chan);
++ sip_pvt_lock(pvt);
++
++ if (pvt->owner == chan) {
++ /* done */
++ break;
++ }
++
++ /* If the owner changed while everything was unlocked, no problem,
++ * just start over and everthing will work. This is rare, do not be
++ * confused by this loop and think this it is an expensive operation.
++ * The majority of the calls to this function will never involve multiple
++ * executions of this loop. */
++ ast_channel_unlock(chan);
++ ao2_ref(chan, -1); //ast_channel_unref(chan);
++ sip_pvt_unlock(pvt);
++ }
++
++ /* If owner exists, it is locked and reffed */
++ return pvt->owner;
++}
++
+ /*! \brief find or create a dialog structure for an incoming SIP message.
+ * Connect incoming SIP message to current dialog or create new dialog structure
+ * Returns a reference to the sip_pvt object, remember to give it back once done.
+@@ -10715,7 +10808,7 @@
initialize_initreq(p, &req);
p->lastinvite = p->ocseq;
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */
@@ -94,7 +179,7 @@
return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
}
-@@ -17736,17 +17760,20 @@
+@@ -17736,17 +17829,20 @@
static void check_pendings(struct sip_pvt *p)
{
if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
@@ -121,7 +206,7 @@
/* Perhaps there is an SD change INVITE outstanding */
transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
}
-@@ -17821,9 +17848,17 @@
+@@ -17821,9 +17917,17 @@
if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
p->invitestate = INV_COMPLETED;
More information about the Pkg-voip-commits
mailing list