[asterisk-commits] russell: branch 1.8 r351182 - /branches/1.8/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jan 16 19:37:09 CST 2012
Author: russell
Date: Mon Jan 16 19:37:03 2012
New Revision: 351182
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=351182
Log:
Add some missing locking in chan_sip.
This patch adds some missing locking to the function
send_provisional_keepalive_full(). This function is called from the scheduler,
which is processed in the SIP monitor thread. The associated channel (or pbx)
thread will also be using the same sip_pvt and ast_channel so locking must be
used. The sip_pvt_lock_full() function is used to ensure proper locking order
in a safe manner.
In passing, document a suspected reference counting error in this function.
The "fix" is left commented out because when the "fix" is present, crashes
occur. My theory is that fixing it is exposing a reference counting error
elsewhere, but I don't know where. (Or my analysis of this being a problem
could have been completely wrong in the first place). Leave the comment in
the code for so that someone may investigate it again in the future.
Also add a bit of doxygen to transmit_provisional_response().
(closes issue ASTERISK-18979)
Review: https://reviewboard.asterisk.org/r/1648
Modified:
branches/1.8/channels/chan_sip.c
Modified: branches/1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_sip.c?view=diff&rev=351182&r1=351181&r2=351182
==============================================================================
--- branches/1.8/channels/chan_sip.c (original)
+++ branches/1.8/channels/chan_sip.c Mon Jan 16 19:37:03 2012
@@ -4074,6 +4074,10 @@
static int send_provisional_keepalive_full(struct sip_pvt *pvt, int with_sdp)
{
const char *msg = NULL;
+ struct ast_channel *chan;
+ int res = 0;
+
+ chan = sip_pvt_lock_full(pvt);
if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
msg = "183 Session Progress";
@@ -4085,10 +4089,35 @@
} else {
transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
}
- return PROVIS_KEEPALIVE_TIMEOUT;
- }
-
- return 0;
+ res = PROVIS_KEEPALIVE_TIMEOUT;
+ }
+
+ if (chan) {
+ ast_channel_unlock(chan);
+ chan = ast_channel_unref(chan);
+ }
+
+ if (!res) {
+ pvt->provisional_keepalive_sched_id = -1;
+ }
+
+ sip_pvt_unlock(pvt);
+
+#if 0
+ /*
+ * XXX BUG TODO
+ *
+ * Without this code, it appears as if this function is leaking its
+ * reference to the sip_pvt. However, adding it introduces a crash.
+ * This points to some sort of reference count imbalance elsewhere,
+ * but I'm not sure where ...
+ */
+ if (!res) {
+ dialog_unref(pvt, "dialog ref for provisional keepalive");
+ }
+#endif
+
+ return res;
}
static int send_provisional_keepalive(const void *data) {
@@ -10681,7 +10710,13 @@
ast_string_field_set(p, realm, sip_cfg.realm);
}
-/* Only use a static string for the msg, here! */
+/*!
+ * \internal
+ *
+ * \arg msg Only use a string constant for the msg, here, it is shallow copied
+ *
+ * \note assumes the sip_pvt is locked.
+ */
static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
{
int res;
More information about the asterisk-commits
mailing list