mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-25 15:08:53 +00:00
Merged revisions 67020 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r67020 | russell | 2007-06-04 10:47:40 -0500 (Mon, 04 Jun 2007) | 7 lines Resolve a deadlock in chan_iax2. When handling an implicit ACK to a frame that was marked as the final transmission for a call, don't call iax2_destroy() for that call while the global frame queue is still locked. There is a very nice explanation of the deadlock in the report. (issue #9663, thorough report and patch from stevedavies, additional positive test reports from mihai and joff_oconnell) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@67022 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -6844,6 +6844,7 @@ static int socket_process(struct iax2_thread *thread)
|
|||||||
((f.subclass != IAX_COMMAND_INVAL) ||
|
((f.subclass != IAX_COMMAND_INVAL) ||
|
||||||
(f.frametype != AST_FRAME_IAX))) {
|
(f.frametype != AST_FRAME_IAX))) {
|
||||||
unsigned char x;
|
unsigned char x;
|
||||||
|
int call_to_destroy;
|
||||||
/* XXX This code is not very efficient. Surely there is a better way which still
|
/* XXX This code is not very efficient. Surely there is a better way which still
|
||||||
properly handles boundary conditions? XXX */
|
properly handles boundary conditions? XXX */
|
||||||
/* First we have to qualify that the ACKed value is within our window */
|
/* First we have to qualify that the ACKed value is within our window */
|
||||||
@@ -6857,20 +6858,23 @@ static int socket_process(struct iax2_thread *thread)
|
|||||||
/* Ack the packet with the given timestamp */
|
/* Ack the packet with the given timestamp */
|
||||||
if (option_debug && iaxdebug)
|
if (option_debug && iaxdebug)
|
||||||
ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
|
ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
|
||||||
|
call_to_destroy = 0;
|
||||||
AST_LIST_LOCK(&queue);
|
AST_LIST_LOCK(&queue);
|
||||||
AST_LIST_TRAVERSE(&queue, cur, list) {
|
AST_LIST_TRAVERSE(&queue, cur, list) {
|
||||||
/* If it's our call, and our timestamp, mark -1 retries */
|
/* If it's our call, and our timestamp, mark -1 retries */
|
||||||
if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
|
if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
|
||||||
cur->retries = -1;
|
cur->retries = -1;
|
||||||
/* Destroy call if this is the end */
|
/* Destroy call if this is the end */
|
||||||
if (cur->final) {
|
if (cur->final)
|
||||||
if (iaxdebug && option_debug)
|
call_to_destroy = fr->callno;
|
||||||
ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
|
|
||||||
iax2_destroy(fr->callno);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AST_LIST_UNLOCK(&queue);
|
AST_LIST_UNLOCK(&queue);
|
||||||
|
if (call_to_destroy) {
|
||||||
|
if (iaxdebug && option_debug)
|
||||||
|
ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
|
||||||
|
iax2_destroy(call_to_destroy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Note how much we've received acknowledgement for */
|
/* Note how much we've received acknowledgement for */
|
||||||
if (iaxs[fr->callno])
|
if (iaxs[fr->callno])
|
||||||
|
Reference in New Issue
Block a user