diff options
author | Richard Mudgett <rmudgett@digium.com> | 2011-08-31 15:25:35 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2011-08-31 15:25:35 +0000 |
commit | ab17a27f972ef4f3cc14ffcab746c346452149bd (patch) | |
tree | 86a2edb976791d381cdde343462a1678f81d1b8d /channels/chan_agent.c | |
parent | 82229cc690948faf7fd86f8e6ff3743012ee2e57 (diff) |
Merged revisions 334010 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/10
................
r334010 | rmudgett | 2011-08-31 10:23:11 -0500 (Wed, 31 Aug 2011) | 50 lines
Merged revisions 334009 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r334009 | rmudgett | 2011-08-31 10:20:31 -0500 (Wed, 31 Aug 2011) | 43 lines
Call pickup race leaves orphaned channels or crashes.
Multiple users attempting to pickup a call that has been forked to
multiple extensions either crashes or fails a masquerade with a "bad
things may happen" message.
This is the scenario that is causing all the grief:
1) Pickup target is selected
2) target is marked as being picked up in ast_do_pickup()
3) target is unlocked by ast_do_pickup()
4) app dial or queue gets a chance to hang up losing calls and calls
ast_hangup() on target
5) SINCE A MASQUERADE HAS NOT BEEN SETUP YET BY ast_do_pickup() with
ast_channel_masquerade(), ast_hangup() completes successfully and the
channel is no longer in the channels container.
6) ast_do_pickup() then calls ast_channel_masquerade() to schedule the
masquerade on the dead channel.
7) ast_do_pickup() then calls ast_do_masquerade() on the dead channel
8) bad things happen while doing the masquerade and in the process
ast_do_masquerade() puts the dead channel back into the channels container
9) The "orphaned" channel is visible in the channels list if a crash does
not happen.
This patch does the following:
* Made ast_hangup() set AST_FLAG_ZOMBIE on a successfully hung-up channel
and not release the channel lock until that has happened.
* Made __ast_channel_masquerade() not setup a masquerade if either channel
has AST_FLAG_ZOMBIE set.
* Fix chan_agent misuse of AST_FLAG_ZOMBIE since it would no longer work.
(closes issue ASTERISK-18222)
Reported by: Alec Davis
Tested by: rmudgett, Alec Davis, irroot, Karsten Wemheuer
(closes issue ASTERISK-18273)
Reported by: Karsten Wemheuer
Tested by: rmudgett, Alec Davis, irroot, Karsten Wemheuer
Review: https://reviewboard.asterisk.org/r/1400/
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@334011 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_agent.c')
-rw-r--r-- | channels/chan_agent.c | 4 |
1 files changed, 1 insertions, 3 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 044524669..6e17f1be9 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -1301,10 +1301,8 @@ static int check_availability(struct agent_pvt *newlyavailable, int needlock) ast_setstate(parent, AST_STATE_UP); ast_setstate(chan, AST_STATE_UP); ast_copy_string(parent->context, chan->context, sizeof(parent->context)); - /* Go ahead and mark the channel as a zombie so that masquerade will - destroy it for us, and we need not call ast_hangup */ - ast_set_flag(chan, AST_FLAG_ZOMBIE); ast_channel_masquerade(parent, chan); + ast_hangup(chan); p->abouttograb = 0; } else { ast_debug(1, "Sneaky, parent disappeared in the mean time...\n"); |