aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_agent.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-03-20 17:21:54 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-03-20 17:21:54 +0000
commit3d4c6ea82a08d9703653f7d8838fabef81da63b6 (patch)
tree000f12071b6f97c254068faa7c82566df7f986d1 /channels/chan_agent.c
parentb8540d24188d6f657c28b842c0d32fa1e60af3c6 (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-xchannels/chan_agent.c65
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",