mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-09 11:28:25 +00:00
chan_iax2: Fix bridgecallno deadlock avoidance.
* Fix bridgecallno deadlock avoidance. When doing deadlock avoidance, you need to retest the status of values for each loop to see if you still need the lock for bridgecallno. * As a safety check, after acquiring the bridgecallno lock you should check if iaxs[bridgecallno] is NULL just like the current callno checks. * Move setting thread->iostate to IAX_IOSTATE_IDLE to after processing any deferred frames to ensure that the iostate is IDLE when it is placed back into the idle list. defer_full_frame() tries to ensure iax2_process_thread() wakes up to process the frame. ........ Merged revisions 398379 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 398380 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@398381 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -831,7 +831,7 @@ struct chan_iax2_pvt {
|
|||||||
/*! Status of knowledge of peer ADSI capability */
|
/*! Status of knowledge of peer ADSI capability */
|
||||||
int peeradsicpe;
|
int peeradsicpe;
|
||||||
|
|
||||||
/*! Who we are bridged to */
|
/*! Callno of native bridge peer. (Valid if nonzero) */
|
||||||
unsigned short bridgecallno;
|
unsigned short bridgecallno;
|
||||||
|
|
||||||
int pingid; /*!< Transmit PING request */
|
int pingid; /*!< Transmit PING request */
|
||||||
@@ -11221,13 +11221,13 @@ immediatedial:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IAX_COMMAND_TXREJ:
|
case IAX_COMMAND_TXREJ:
|
||||||
if (iaxs[fr->callno]->bridgecallno) {
|
while (iaxs[fr->callno]
|
||||||
while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
|
&& iaxs[fr->callno]->bridgecallno
|
||||||
DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
|
&& ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
|
||||||
}
|
DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
|
||||||
if (!iaxs[fr->callno]) {
|
}
|
||||||
break;
|
if (!iaxs[fr->callno]) {
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iaxs[fr->callno]->transferring = TRANSFER_NONE;
|
iaxs[fr->callno]->transferring = TRANSFER_NONE;
|
||||||
@@ -11238,20 +11238,21 @@ immediatedial:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
|
if (iaxs[iaxs[fr->callno]->bridgecallno]
|
||||||
|
&& iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
|
||||||
iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
|
iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
|
||||||
send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
|
send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
|
||||||
}
|
}
|
||||||
ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
|
ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
|
||||||
break;
|
break;
|
||||||
case IAX_COMMAND_TXREADY:
|
case IAX_COMMAND_TXREADY:
|
||||||
if (iaxs[fr->callno]->bridgecallno) {
|
while (iaxs[fr->callno]
|
||||||
while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
|
&& iaxs[fr->callno]->bridgecallno
|
||||||
DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
|
&& ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
|
||||||
}
|
DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
|
||||||
if (!iaxs[fr->callno]) {
|
}
|
||||||
break;
|
if (!iaxs[fr->callno]) {
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
|
if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
|
||||||
@@ -11270,8 +11271,9 @@ immediatedial:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) &&
|
if (!iaxs[iaxs[fr->callno]->bridgecallno]
|
||||||
!(iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
|
|| (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
|
||||||
|
&& iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
|
||||||
ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
|
ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -11655,11 +11657,10 @@ static void *iax2_process_thread(void *data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread->iostate == IAX_IOSTATE_IDLE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* See what we need to do */
|
/* See what we need to do */
|
||||||
switch (thread->iostate) {
|
switch (thread->iostate) {
|
||||||
|
case IAX_IOSTATE_IDLE:
|
||||||
|
continue;
|
||||||
case IAX_IOSTATE_READY:
|
case IAX_IOSTATE_READY:
|
||||||
thread->actions++;
|
thread->actions++;
|
||||||
thread->iostate = IAX_IOSTATE_PROCESSING;
|
thread->iostate = IAX_IOSTATE_PROCESSING;
|
||||||
@@ -11672,14 +11673,10 @@ static void *iax2_process_thread(void *data)
|
|||||||
#ifdef SCHED_MULTITHREADED
|
#ifdef SCHED_MULTITHREADED
|
||||||
thread->schedfunc(thread->scheddata);
|
thread->schedfunc(thread->scheddata);
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
time(&thread->checktime);
|
|
||||||
thread->iostate = IAX_IOSTATE_IDLE;
|
|
||||||
#ifdef DEBUG_SCHED_MULTITHREAD
|
|
||||||
thread->curfunc[0]='\0';
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The network thread added us to the active_thread list when we were given
|
/* The network thread added us to the active_thread list when we were given
|
||||||
* frames to process, Now that we are done, we must remove ourselves from
|
* frames to process, Now that we are done, we must remove ourselves from
|
||||||
@@ -11690,6 +11687,12 @@ static void *iax2_process_thread(void *data)
|
|||||||
|
|
||||||
/* Make sure another frame didn't sneak in there after we thought we were done. */
|
/* Make sure another frame didn't sneak in there after we thought we were done. */
|
||||||
handle_deferred_full_frames(thread);
|
handle_deferred_full_frames(thread);
|
||||||
|
|
||||||
|
time(&thread->checktime);
|
||||||
|
thread->iostate = IAX_IOSTATE_IDLE;
|
||||||
|
#ifdef DEBUG_SCHED_MULTITHREAD
|
||||||
|
thread->curfunc[0]='\0';
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
Reference in New Issue
Block a user