From ecd9868ec2830d7ea35447282f973d91b69f70b1 Mon Sep 17 00:00:00 2001 From: jpeeler Date: Tue, 19 Jan 2010 18:58:10 +0000 Subject: 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.0@241316 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_agent.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 01cefb1ba..72b90a44e 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -489,7 +489,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) { -- cgit v1.2.3