diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-03-20 17:21:54 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-03-20 17:21:54 +0000 |
commit | 3d4c6ea82a08d9703653f7d8838fabef81da63b6 (patch) | |
tree | 000f12071b6f97c254068faa7c82566df7f986d1 /channels/chan_agent.c | |
parent | b8540d24188d6f657c28b842c0d32fa1e60af3c6 (diff) |
Merge some of Mahmut's patches
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@666 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_agent.c')
-rwxr-xr-x | channels/chan_agent.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 61f5bb29b..0b3d74e84 100755 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -223,21 +223,36 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout) struct agent_pvt *p = ast->pvt->pvt; int res = -1; ast_pthread_mutex_lock(&p->lock); + ast_verbose( VERBOSE_PREFIX_3 "agent_call, call to agent '%s' call on '%s'\n", p->agent, p->chan->name); + ast_log( LOG_DEBUG, "Playing beep, lang '%s'\n", p->chan->language); res = ast_streamfile(p->chan, "beep", p->chan->language); - if (!res) + ast_log( LOG_DEBUG, "Played beep, result '%d'\n", res); + if (!res) { res = ast_waitstream(p->chan, ""); + ast_log( LOG_DEBUG, "Waited for stream, result '%d'\n", res); + } if (!res) { res = ast_set_read_format(p->chan, ast_best_codec(p->chan->nativeformats)); + ast_log( LOG_DEBUG, "Set read format, result '%d'\n", res); if (res) ast_log(LOG_WARNING, "Unable to set read format to %d\n", ast_best_codec(p->chan->nativeformats)); } + else { + // Agent hung-up + p->chan = NULL; + } + if (!res) { ast_set_write_format(p->chan, ast_best_codec(p->chan->nativeformats)); + ast_log( LOG_DEBUG, "Set write format, result '%d'\n", res); if (res) ast_log(LOG_WARNING, "Unable to set write format to %d\n", ast_best_codec(p->chan->nativeformats)); } - /* Call is immediately up */ - ast_setstate(ast, AST_STATE_UP); + if( !res ) + { + /* Call is immediately up */ + ast_setstate(ast, AST_STATE_UP); + } CLEANUP(ast,p); ast_pthread_mutex_unlock(&p->lock); return res; @@ -250,9 +265,6 @@ static int agent_hangup(struct ast_channel *ast) p->owner = NULL; ast->pvt->pvt = NULL; p->app_sleep_cond = 1; - ast_pthread_mutex_unlock(&p->lock); - /* Release ownership of the agent to other threads (presumably running the login app). */ - ast_pthread_mutex_unlock(&p->app_lock); if (p->chan) { /* If they're dead, go ahead and hang up on the agent now */ ast_pthread_mutex_lock(&p->chan->lock); @@ -260,9 +272,20 @@ static int agent_hangup(struct ast_channel *ast) ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT); ast_moh_start(p->chan, p->moh); ast_pthread_mutex_unlock(&p->chan->lock); - } else if (p->dead) + ast_pthread_mutex_unlock(&p->lock); + /* Release ownership of the agent to other threads (presumably running the login app). */ + ast_pthread_mutex_unlock(&p->app_lock); + } else if (p->dead) { /* Go ahead and lose it */ + ast_pthread_mutex_unlock(&p->lock); + /* Release ownership of the agent to other threads (presumably running the login app). */ + ast_pthread_mutex_unlock(&p->app_lock); free(p); + } else { + ast_pthread_mutex_unlock(&p->lock); + /* Release ownership of the agent to other threads (presumably running the login app). */ + ast_pthread_mutex_unlock(&p->app_lock); + } return 0; } @@ -333,6 +356,15 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state) ast_pthread_mutex_unlock(&p->lock); /* For other thread to read the condition. */ ast_pthread_mutex_lock(&p->app_lock); ast_pthread_mutex_lock(&p->lock); + if( !p->chan ) + { + ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n"); + p->owner = NULL; + tmp->pvt->pvt = NULL; + p->app_sleep_cond = 1; + ast_channel_free( tmp ); + return NULL; + } } p->owning_app = pthread_self(); /* After the above step, there should not be any blockers. */ @@ -486,9 +518,6 @@ static int login_exec(struct ast_channel *chan, void *data) char *opt_user = NULL; char *options = NULL; int play_announcement; - struct timespec required; - struct timespec remaining; - int delay; LOCAL_USER_ADD(u); @@ -577,21 +606,12 @@ static int login_exec(struct ast_channel *chan, void *data) ast_pthread_mutex_unlock(&p->lock); ast_pthread_mutex_unlock(&agentlock); while (res >= 0) { - /* If we are not the owner, delay here for a while - * so other interested threads can kick in. */ - delay = 0; ast_pthread_mutex_lock(&p->lock); if (p->chan != chan) res = -1; - if (p->owner) - delay = 1; ast_pthread_mutex_unlock(&p->lock); - if (delay) { - sched_yield(); - required.tv_sec = 0; - required.tv_nsec = 20 * 1000 * 1000; - nanosleep( &required, &remaining ); - } + /* Yield here so other interested threads can kick in. */ + sched_yield(); if (res) break; @@ -603,12 +623,15 @@ static int login_exec(struct ast_channel *chan, void *data) res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p ); pthread_mutex_unlock( &p->app_lock ); + sched_yield(); } + ast_pthread_mutex_lock(&p->lock); if (res && p->owner) ast_log(LOG_WARNING, "Huh? We broke out when there was still an owner?\n"); /* Log us off if appropriate */ if (p->chan == chan) p->chan = NULL; + ast_pthread_mutex_unlock(&p->lock); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Agent '%s' logged out\n", p->agent); manager_event(EVENT_FLAG_AGENT, "Agentlogoff", |