diff options
author | rmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-13 19:06:55 +0000 |
---|---|---|
committer | rmudgett <rmudgett@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-13 19:06:55 +0000 |
commit | 3e60d9c63b217cbd6f30a94243321a55454b8cdf (patch) | |
tree | a2d01b8dc4829b88425aeaf0afa2581023bc285b /channels/chan_misdn.c | |
parent | ee7189535a22e70b274f91da042118918bd6e23f (diff) |
Merged revisions 291507 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
................
r291507 | rmudgett | 2010-10-13 14:01:48 -0500 (Wed, 13 Oct 2010) | 18 lines
Merged revision 291504 from
https://origsvn.digium.com/svn/asterisk/be/branches/C.3-bier
..........
r291504 | rmudgett | 2010-10-13 13:30:21 -0500 (Wed, 13 Oct 2010) | 11 lines
Hold off ast_hangup() from destroying the ast_channel.
Must get the ast_channel lock before proceeding with release_chan() and
release_chan_early() to hold off ast_hangup() from destroying the
ast_channel.
Missed this change for -r291468.
JIRA ABE-2598
JIRA SWP-2317
..........
................
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@291508 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r-- | channels/chan_misdn.c | 84 |
1 files changed, 49 insertions, 35 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 4a788483d..a6d623e7a 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -8332,16 +8332,42 @@ static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc) { struct ast_channel *ast; + chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id); + ast_mutex_lock(&release_lock); + for (;;) { + ast = ch->ast; + if (!ast || !ast_channel_trylock(ast)) { + break; + } + DEADLOCK_AVOIDANCE(&release_lock); + } if (!cl_dequeue_chan(ch)) { /* Someone already released it. */ + if (ast) { + ast_channel_unlock(ast); + } ast_mutex_unlock(&release_lock); return; } ch->state = MISDN_CLEANING; - ast = ch->ast; ch->ast = NULL; - ast_mutex_unlock(&release_lock); + if (ast) { + MISDN_ASTERISK_TECH_PVT(ast) = NULL; + chan_misdn_log(1, bc->port, + "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n", + bc->pid, + ast->context, + ast->exten, + S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""), + S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, "")); + + if (ast->_state != AST_STATE_RESERVED) { + chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); + ast_setstate(ast, AST_STATE_DOWN); + } + ast_channel_unlock(ast); + } #if defined(AST_MISDN_ENHANCEMENTS) if (ch->peer) { @@ -8355,8 +8381,6 @@ static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc) ch->dsp = NULL; } - chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id); - /* releasing jitterbuffer */ if (ch->jb) { misdn_jb_destroy(ch->jb); @@ -8384,27 +8408,9 @@ static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc) close(ch->pipe[0]); close(ch->pipe[1]); - if (ast) { - ast_channel_lock(ast); - MISDN_ASTERISK_TECH_PVT(ast) = NULL; - chan_misdn_log(1, bc->port, - "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n", - bc->pid, - ast->context, - ast->exten, - (ast->caller.id.name.valid && ast->caller.id.name.str) - ? ast->caller.id.name.str : "", - (ast->caller.id.number.valid && ast->caller.id.number.str) - ? ast->caller.id.number.str : ""); - - if (ast->_state != AST_STATE_RESERVED) { - chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); - ast_setstate(ast, AST_STATE_DOWN); - } - ast_channel_unlock(ast); - } - ast_free(ch); + + ast_mutex_unlock(&release_lock); } /*! @@ -8422,15 +8428,30 @@ static void release_chan_early(struct chan_list *ch) struct ast_channel *ast; ast_mutex_lock(&release_lock); + for (;;) { + ast = ch->ast; + if (!ast || !ast_channel_trylock(ast)) { + break; + } + DEADLOCK_AVOIDANCE(&release_lock); + } if (!cl_dequeue_chan(ch)) { /* Someone already released it. */ + if (ast) { + ast_channel_unlock(ast); + } ast_mutex_unlock(&release_lock); return; } ch->state = MISDN_CLEANING; - ast = ch->ast; ch->ast = NULL; - ast_mutex_unlock(&release_lock); + if (ast) { + MISDN_ASTERISK_TECH_PVT(ast) = NULL; + if (ast->_state != AST_STATE_RESERVED) { + ast_setstate(ast, AST_STATE_DOWN); + } + ast_channel_unlock(ast); + } #if defined(AST_MISDN_ENHANCEMENTS) if (ch->peer) { @@ -8469,16 +8490,9 @@ static void release_chan_early(struct chan_list *ch) close(ch->pipe[0]); close(ch->pipe[1]); - if (ast) { - ast_channel_lock(ast); - MISDN_ASTERISK_TECH_PVT(ast) = NULL; - if (ast->_state != AST_STATE_RESERVED) { - ast_setstate(ast, AST_STATE_DOWN); - } - ast_channel_unlock(ast); - } - ast_free(ch); + + ast_mutex_unlock(&release_lock); } /*! |