[asterisk-commits] rmudgett: branch 10 r344004 - /branches/10/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Nov 8 15:59:55 CST 2011
Author: rmudgett
Date: Tue Nov 8 15:59:49 2011
New Revision: 344004
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=344004
Log:
Residual changes for Asterisk v10 branch from ASTERISK-18747.
Residual changes for Asterisk v10 branch from ASTERISK-18747 after
https://reviewboard.asterisk.org/r/1564/ commit and associated dialogs
callid hash key change fix.
* Make check_rtp_timeout() return CMP_MATCH if need to delete dialog from
dialogs_rtpcheck. This is an optimization to avoid an unneeded
lock/unlock and object search when using ao2_unlink.
* Prevent crash in check_rtp_timeout() if dialog->rtp is NULL.
Review: https://reviewboard.asterisk.org/r/1557/
Modified:
branches/10/channels/chan_sip.c
Modified: branches/10/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/channels/chan_sip.c?view=diff&rev=344004&r1=344003&r2=344004
==============================================================================
--- branches/10/channels/chan_sip.c (original)
+++ branches/10/channels/chan_sip.c Tue Nov 8 15:59:49 2011
@@ -1075,21 +1075,24 @@
}
}
-/*! \brief
+/*!
+ * \details
* Here we implement the container for dialogs which are in the
* dialog_needdestroy state to iterate only through the dialogs
* unlink them instead of iterate through all dialogs
*/
struct ao2_container *dialogs_needdestroy;
-/*! \brief
+/*!
+ * \details
* Here we implement the container for dialogs which have rtp
* traffic and rtptimeout, rtpholdtimeout or rtpkeepalive
* set. We use this container instead the whole dialog list.
*/
struct ao2_container *dialogs_rtpcheck;
-/*! \brief
+/*!
+ * \details
* Here we implement the container for dialogs (sip_pvt), defining
* generic wrapper functions to ease the transition from the current
* implementation (a single linked list) to a different container.
@@ -1338,7 +1341,7 @@
static struct sip_auth *find_realm_authentication(struct sip_auth_container *credentials, const char *realm);
/*--- Misc functions */
-static void check_rtp_timeout(struct sip_pvt *dialog, time_t t);
+static int check_rtp_timeout(struct sip_pvt *dialog, time_t t);
static int reload_config(enum channelreloadreason reason);
static void add_diversion_header(struct sip_request *req, struct sip_pvt *pvt);
static int expire_register(const void *data);
@@ -2945,15 +2948,6 @@
}
}
- /*!
- * \brief Unlink a dialog from the dialogs_checkrtp container
- */
-static void *dialog_unlink_rtpcheck(struct sip_pvt *dialog)
-{
- ao2_t_unlink(dialogs_rtpcheck, dialog, "unlinking dialog_rtpcheck via ao2_unlink");
- return NULL;
-}
-
/*!
* \brief Unlink a dialog from the dialogs container, as well as any other places
* that it may be currently stored.
@@ -3074,11 +3068,11 @@
if (pvt->final_destruction_scheduled) {
return; /* This is already scheduled for final destruction, let the scheduler take care of it. */
}
- if(pvt->needdestroy != 1) {
+ append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
+ if (!pvt->needdestroy) {
+ pvt->needdestroy = 1;
ao2_t_link(dialogs_needdestroy, pvt, "link pvt into dialogs_needdestroy container");
}
- append_history(pvt, "NeedDestroy", "Setting needdestroy because %s", reason);
- pvt->needdestroy = 1;
}
/*! \brief Initialize the initital request packet in the pvt structure.
@@ -6265,7 +6259,6 @@
ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
- p->needdestroy = 0;
p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt");
sip_pvt_lock(p);
p->owner = NULL; /* Owner will be gone after we return, so take it away */
@@ -11722,9 +11715,14 @@
/* Update lastrtprx when we send our SDP */
p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
- /* we unlink this dialog and link again into the dialogs_rtpcheck container to doesnt add it twice */
+ /*
+ * We unlink this dialog and link again into the
+ * dialogs_rtpcheck container so its not in there twice.
+ */
+ ao2_lock(dialogs_rtpcheck);
ao2_t_unlink(dialogs_rtpcheck, p, "unlink pvt into dialogs_rtpcheck container");
ao2_t_link(dialogs_rtpcheck, p, "link pvt into dialogs_rtpcheck container");
+ ao2_unlock(dialogs_rtpcheck);
ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmpcap));
@@ -17076,28 +17074,33 @@
}
}
-/*! \brief Check RTP Timeout on dialogs
+/*!
+ * \brief Check RTP Timeout on dialogs
+ *
* \details This is used with ao2_callback to check rtptimeout
- * rtponholdtimeout and send rtpkeepalive packets
+ * rtponholdtimeout and send rtpkeepalive packets.
+ *
+ * \return CMP_MATCH for items to be unlinked from dialogs_rtpcheck.
*/
static int dialog_checkrtp_cb(void *dialogobj, void *arg, int flags)
{
struct sip_pvt *dialog = dialogobj;
time_t *t = arg;
+ int match_status;
if (sip_pvt_trylock(dialog)) {
return 0;
}
if (dialog->rtp || dialog->vrtp) {
- check_rtp_timeout(dialog, *t);
+ match_status = check_rtp_timeout(dialog, *t);
} else {
- /* Dialog has no active RTP or VRTP. unlink it from the checkrtp container */
- dialog_unlink_rtpcheck(dialog);
+ /* Dialog has no active RTP or VRTP. unlink it from dialogs_rtpcheck. */
+ match_status = CMP_MATCH;
}
sip_pvt_unlock(dialog);
- return 0;
+ return match_status;
}
/*!
@@ -17119,7 +17122,6 @@
* that we can wait for the next time around. */
return 0;
}
-
/* If we have sessions that needs to be destroyed, do it now */
/* Check if we have outstanding requests not responsed to or an active call
@@ -25953,35 +25955,43 @@
return 0;
}
-/*! \brief helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked */
-static void check_rtp_timeout(struct sip_pvt *dialog, time_t t)
-{
+/*!
+ * \brief helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
+ *
+ * \return CMP_MATCH for items to be unlinked from dialogs_rtpcheck.
+ */
+static int check_rtp_timeout(struct sip_pvt *dialog, time_t t)
+{
+ if (!dialog->rtp) {
+ /*
+ * We have no RTP. Since we don't do much with video RTP for
+ * now, stop checking this dialog.
+ */
+ return CMP_MATCH;
+ }
+
/* If we have no active owner, no need to check timers */
if (!dialog->owner) {
- dialog_unlink_rtpcheck(dialog);
- return;
- }
+ return CMP_MATCH;
+ }
+
/* If the call is redirected outside Asterisk, no need to check timers */
-
if (!ast_sockaddr_isnull(&dialog->redirip)) {
- dialog_unlink_rtpcheck(dialog);
- return;
+ return CMP_MATCH;
}
/* If the call is involved in a T38 fax session do not check RTP timeout */
if (dialog->t38.state == T38_ENABLED) {
- dialog_unlink_rtpcheck(dialog);
- return;
+ return CMP_MATCH;
}
/* If the call is not in UP state return for later check. */
if (dialog->owner->_state != AST_STATE_UP) {
- return;
+ return 0;
}
/* If we have no timers set, return now */
if (!ast_rtp_instance_get_keepalive(dialog->rtp) && !ast_rtp_instance_get_timeout(dialog->rtp) && !ast_rtp_instance_get_hold_timeout(dialog->rtp)) {
- dialog_unlink_rtpcheck(dialog);
- return;
+ return CMP_MATCH;
}
/* Check AUDIO RTP keepalives */
@@ -26008,7 +26018,7 @@
* Don't block, just try again later.
* If there was no owner, the call is dead already.
*/
- return;
+ return 0;
}
ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
dialog->owner->name, (long) (t - dialog->lastrtprx));
@@ -26025,10 +26035,12 @@
ast_rtp_instance_set_timeout(dialog->vrtp, 0);
ast_rtp_instance_set_hold_timeout(dialog->vrtp, 0);
}
- dialog_unlink_rtpcheck(dialog); /* finally unlink the dialog from the checkrtp container */
- }
- }
- }
+ /* finally unlink the dialog from dialogs_rtpcheck. */
+ return CMP_MATCH;
+ }
+ }
+ }
+ return 0;
}
/*! \brief The SIP monitoring thread
@@ -26070,15 +26082,20 @@
/* Check for dialogs needing to be killed */
t = time(NULL);
- /* Check for dialogs with rtp and rtptimeout
- * All Dialogs which have rtp are in dialogs_rtpcheck container*/
- ao2_t_callback(dialogs_rtpcheck, OBJ_NODATA | OBJ_MULTIPLE, dialog_checkrtp_cb, &t,
- "callback to check rtptimeout and hangup calls if necessary");
-
- /* Check for dialogs marked to be destroyed
- * All Dialogs which need Destroy are in dialogs_needdestroy container*/
- ao2_t_callback(dialogs_needdestroy, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t,
- "callback to check rtptimeout and hangup calls if necessary");
+
+ /*
+ * Check dialogs with rtp and rtptimeout.
+ * All dialogs which have rtp are in dialogs_rtpcheck.
+ */
+ ao2_t_callback(dialogs_rtpcheck, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE,
+ dialog_checkrtp_cb, &t,
+ "callback to check rtptimeout and hangup calls if necessary");
+ /*
+ * Check dialogs marked to be destroyed.
+ * All dialogs with needdestroy set are in dialogs_needdestroy.
+ */
+ ao2_t_callback(dialogs_needdestroy, OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy,
+ NULL, "callback to check dialogs which need to be destroyed");
/* XXX TODO The scheduler usage in this module does not have sufficient
* synchronization being done between running the scheduler and places
More information about the asterisk-commits
mailing list