diff options
author | jpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-01-19 19:01:09 +0000 |
---|---|---|
committer | jpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-01-19 19:01:09 +0000 |
commit | d9280e2422858d1f6c3c568142fa8293cda331f0 (patch) | |
tree | abbc4cacf29c992b824a49636b7ad6d533e0bfe5 | |
parent | b41572229930e97e7604ad478c3a56749af4dd4c (diff) |
Merged revisions 241314 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
................
r241314 | jpeeler | 2010-01-19 12:46:11 -0600 (Tue, 19 Jan 2010) | 20 lines
Merged revisions 241227 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r241227 | jpeeler | 2010-01-19 11:22:18 -0600 (Tue, 19 Jan 2010) | 13 lines
Fix deadlock in agent_read by removing call to agent_logoff.
One must always lock the agents list lock before the agent private. agent_read
locks the private immediately, so locking the agents list lock is not an
option (which is what agent_logoff requires). Because agent_read already
has access to the agent private all that is necessary is to do the required
hanging up that agent_logoff performed.
(closes issue #16321)
Reported by: valon24
Patches:
bug16321.patch uploaded by jpeeler (license 325)
........
................
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@241317 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | channels/chan_agent.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c index f18461e2e..2d93ecc3c 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -505,7 +505,28 @@ static struct ast_frame *agent_read(struct ast_channel *ast) if (p->autologoff && (howlong >= p->autologoff)) { ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong); agent_logoff_maintenance(p, p->loginchan, (cur_time - p->loginstart), ast->uniqueid, "Autologoff"); - agent_logoff(p->agent, 0); + if (p->owner || p->chan) { + while (p->owner && ast_channel_trylock(p->owner)) { + DEADLOCK_AVOIDANCE(&p->lock); + } + if (p->owner) { + ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT); + ast_channel_unlock(p->owner); + } + + while (p->chan && ast_channel_trylock(p->chan)) { + DEADLOCK_AVOIDANCE(&p->lock); + } + if (p->chan) { + ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT); + ast_channel_unlock(p->chan); + } + } else { + long logintime; + logintime = time(NULL) - p->loginstart; + p->loginstart = 0; + agent_logoff_maintenance(p, p->loginchan, logintime, NULL, "CommandLogoff"); + } } } switch (f->frametype) { |