[asterisk-commits] wedhorn: branch wedhorn/readq-locking r252359 - in /team/wedhorn/readq-lockin...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Mar 14 16:41:07 CDT 2010
Author: wedhorn
Date: Sun Mar 14 16:41:02 2010
New Revision: 252359
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=252359
Log:
Merge old patch into current trunk.
Modified:
team/wedhorn/readq-locking/channels/chan_dahdi.c
team/wedhorn/readq-locking/channels/chan_iax2.c
team/wedhorn/readq-locking/channels/chan_sip.c
team/wedhorn/readq-locking/include/asterisk/channel.h
team/wedhorn/readq-locking/main/channel.c
Modified: team/wedhorn/readq-locking/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/channels/chan_dahdi.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/channels/chan_dahdi.c (original)
+++ team/wedhorn/readq-locking/channels/chan_dahdi.c Sun Mar 14 16:41:02 2010
@@ -2981,58 +2981,16 @@
static void wakeup_sub(struct dahdi_pvt *p, int a)
{
- for (;;) {
- if (p->subs[a].owner) {
- if (ast_channel_trylock(p->subs[a].owner)) {
- DEADLOCK_AVOIDANCE(&p->lock);
- } else {
- ast_queue_frame(p->subs[a].owner, &ast_null_frame);
- ast_channel_unlock(p->subs[a].owner);
- break;
- }
- } else
- break;
+ if (p->subs[a].owner) {
+ ast_queue_frame(p->subs[a].owner, &ast_null_frame);
}
}
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *data)
{
-#ifdef HAVE_SS7
- struct dahdi_ss7 *ss7 = (struct dahdi_ss7*) data;
-
- if (data) {
- switch (p->sig) {
- case SIG_SS7:
- ast_mutex_unlock(&ss7->lock);
- break;
- default:
- break;
- }
- }
-#endif
- for (;;) {
- if (p->owner) {
- if (ast_channel_trylock(p->owner)) {
- DEADLOCK_AVOIDANCE(&p->lock);
- } else {
- ast_queue_frame(p->owner, f);
- ast_channel_unlock(p->owner);
- break;
- }
- } else
- break;
- }
-#if defined(HAVE_SS7)
- if (data) {
- switch (p->sig) {
- case SIG_SS7:
- ast_mutex_lock(&ss7->lock);
- break;
- default:
- break;
- }
- }
-#endif
+ if (p->owner) {
+ ast_queue_frame(p->owner, f);
+ }
}
static void handle_clear_alarms(struct dahdi_pvt *p)
Modified: team/wedhorn/readq-locking/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/channels/chan_iax2.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/channels/chan_iax2.c (original)
+++ team/wedhorn/readq-locking/channels/chan_iax2.c Sun Mar 14 16:41:02 2010
@@ -2807,27 +2807,15 @@
/*!
* \brief Queue a frame to a call's owning asterisk channel
*
- * \pre This function assumes that iaxsl[callno] is locked when called.
+ * \pre This function assumes that iaxsl[callno] is locked when called. No longer applicable.
*
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
+ * \note IMPORTANT NOTE!!! Behaviour changed, iaxs[callno] will exist when this
+ * function ends assuming lock was held before this was called.
*/
static int iax2_queue_frame(int callno, struct ast_frame *f)
{
- for (;;) {
- if (iaxs[callno] && iaxs[callno]->owner) {
- if (ast_channel_trylock(iaxs[callno]->owner)) {
- /* Avoid deadlock by pausing and trying again */
- DEADLOCK_AVOIDANCE(&iaxsl[callno]);
- } else {
- ast_queue_frame(iaxs[callno]->owner, f);
- ast_channel_unlock(iaxs[callno]->owner);
- break;
- }
- } else
- break;
+ if (iaxs[callno] && iaxs[callno]->owner) {
+ ast_queue_frame(iaxs[callno]->owner, f);
}
return 0;
}
@@ -2849,6 +2837,8 @@
{
for (;;) {
if (iaxs[callno] && iaxs[callno]->owner) {
+ /* XXX Locking only required to set chan->_softhangup, not to queue frame */
+ /* wedhorn: planning on changing _softhangup to atomic at which stage we can remove this locking */
if (ast_channel_trylock(iaxs[callno]->owner)) {
/* Avoid deadlock by pausing and trying again */
DEADLOCK_AVOIDANCE(&iaxsl[callno]);
@@ -2869,28 +2859,16 @@
* This function queues a control frame on the owner of the IAX2 pvt struct that
* is active for the given call number.
*
- * \pre Assumes lock for callno is already held.
+ * \pre Assumes lock for callno is already held. No longer applicable.
*
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
+ * \note IMPORTANT NOTE!!! Behaviour changed, iaxs[callno] will exist when this
+ * function ends assuming lock was held before this was called.
*/
static int iax2_queue_control_data(int callno,
enum ast_control_frame_type control, const void *data, size_t datalen)
{
- for (;;) {
- if (iaxs[callno] && iaxs[callno]->owner) {
- if (ast_channel_trylock(iaxs[callno]->owner)) {
- /* Avoid deadlock by pausing and trying again */
- DEADLOCK_AVOIDANCE(&iaxsl[callno]);
- } else {
- ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
- ast_channel_unlock(iaxs[callno]->owner);
- break;
- }
- } else
- break;
+ if (iaxs[callno] && iaxs[callno]->owner) {
+ ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
}
return 0;
}
Modified: team/wedhorn/readq-locking/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/channels/chan_sip.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/channels/chan_sip.c (original)
+++ team/wedhorn/readq-locking/channels/chan_sip.c Sun Mar 14 16:41:02 2010
@@ -4104,12 +4104,8 @@
sip_pvt_lock(p);
p->initid = -1; /* event gone, will not be rescheduled */
if (p->owner) {
- /* XXX fails on possible deadlock */
- if (!ast_channel_trylock(p->owner)) {
- append_history(p, "Cong", "Auto-congesting (timer)");
- ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
- ast_channel_unlock(p->owner);
- }
+ append_history(p, "Cong", "Auto-congesting (timer)");
+ ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
/* Give the channel a chance to act before we proceed with destruction */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
Modified: team/wedhorn/readq-locking/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/include/asterisk/channel.h?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/include/asterisk/channel.h (original)
+++ team/wedhorn/readq-locking/include/asterisk/channel.h Sun Mar 14 16:41:02 2010
@@ -712,7 +712,7 @@
struct varshead varshead; /*!< A linked list for channel variables. See \ref AstChanVar */
ast_group_t callgroup; /*!< Call group for call pickups */
ast_group_t pickupgroup; /*!< Pickup group - which calls groups can be picked up? */
- AST_LIST_HEAD_NOLOCK(, ast_frame) readq;
+ AST_LIST_HEAD(, ast_frame) readq;
AST_LIST_ENTRY(ast_channel) chan_list; /*!< For easy linking */
struct ast_jb jb; /*!< The jitterbuffer state */
struct timeval dtmf_tv; /*!< The time that an in process digit began, or the last digit ended */
Modified: team/wedhorn/readq-locking/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/readq-locking/main/channel.c?view=diff&rev=252359&r1=252358&r2=252359
==============================================================================
--- team/wedhorn/readq-locking/main/channel.c (original)
+++ team/wedhorn/readq-locking/main/channel.c Sun Mar 14 16:41:02 2010
@@ -963,6 +963,8 @@
headp = &tmp->varshead;
AST_LIST_HEAD_INIT_NOLOCK(headp);
+ AST_LIST_HEAD_INIT(&tmp->readq);
+
AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
AST_LIST_HEAD_INIT_NOLOCK(&tmp->autochans);
@@ -1071,13 +1073,13 @@
unsigned int queued_voice_frames = 0;
AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
- ast_channel_lock(chan);
+ AST_LIST_LOCK(&chan->readq);
/* See if the last frame on the queue is a hangup, if so don't queue anything */
if ((cur = AST_LIST_LAST(&chan->readq)) &&
(cur->frametype == AST_FRAME_CONTROL) &&
(cur->subclass.integer == AST_CONTROL_HANGUP)) {
- ast_channel_unlock(chan);
+ AST_LIST_UNLOCK(&chan->readq);
return 0;
}
@@ -1086,7 +1088,7 @@
for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
if (!(f = ast_frdup(cur))) {
ast_frfree(AST_LIST_FIRST(&frames));
- ast_channel_unlock(chan);
+ AST_LIST_UNLOCK(&chan->readq);
return -1;
}
@@ -1144,7 +1146,7 @@
pthread_kill(chan->blocker, SIGURG);
}
- ast_channel_unlock(chan);
+ AST_LIST_UNLOCK(&chan->readq);
return 0;
}
@@ -1904,8 +1906,10 @@
}
close(chan->epfd);
#endif
+ AST_LIST_LOCK(&chan->readq);
while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
ast_frfree(f);
+ AST_LIST_UNLOCK(&chan->readq);
/* loop over the variables list, freeing all data and deleting list items */
/* no need to lock the list, as the channel is already locked */
@@ -3124,6 +3128,8 @@
* point at the end (there are only two exceptions to this).
*/
+ AST_LIST_LOCK(&chan->readq);
+
if (chan->masq) {
if (ast_do_masquerade(chan))
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
@@ -3194,11 +3200,13 @@
int (*func)(const void *) = chan->timingfunc;
void *data = chan->timingdata;
chan->fdno = -1;
+ AST_LIST_UNLOCK(&chan->readq);
ast_channel_unlock(chan);
func(data);
} else {
ast_timer_set_rate(chan->timer, 0);
chan->fdno = -1;
+ AST_LIST_UNLOCK(&chan->readq);
ast_channel_unlock(chan);
}
@@ -3564,6 +3572,7 @@
if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
chan->generator->digit(chan, f->subclass.integer);
+ AST_LIST_UNLOCK(&chan->readq);
ast_channel_unlock(chan);
return f;
}
@@ -5289,6 +5298,8 @@
AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
+ AST_LIST_LOCK(&original->readq);
+
AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
@@ -5302,6 +5313,7 @@
}
}
}
+ AST_LIST_UNLOCK(&original->readq);
}
/* Swap the raw formats */
More information about the asterisk-commits
mailing list