aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_local.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_local.c')
-rw-r--r--channels/chan_local.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 1795e0bb0..747e922fa 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -167,7 +167,8 @@ static struct local_pvt *local_pvt_destroy(struct local_pvt *pvt)
return NULL;
}
-static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
+static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f,
+ struct ast_channel *us, int us_locked)
{
struct ast_channel *other = NULL;
@@ -191,11 +192,13 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra
/* Ensure that we have both channels locked */
while (other && ast_channel_trylock(other)) {
ast_mutex_unlock(&p->lock);
- if (us)
+ if (us && us_locked) {
ast_channel_unlock(us);
+ }
usleep(1);
- if (us)
+ if (us && us_locked) {
ast_channel_lock(us);
+ }
ast_mutex_lock(&p->lock);
other = isoutbound ? p->owner : p->chan;
}
@@ -224,7 +227,7 @@ static int local_answer(struct ast_channel *ast)
if (isoutbound) {
/* Pass along answer since somebody answered us */
struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- res = local_queue_frame(p, isoutbound, &answer, ast);
+ res = local_queue_frame(p, isoutbound, &answer, ast, 1);
} else
ast_log(LOG_WARNING, "Huh? Local is being asked to answer?\n");
if (!res)
@@ -313,7 +316,7 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
check_bridge(p, isoutbound);
if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
- res = local_queue_frame(p, isoutbound, f, ast);
+ res = local_queue_frame(p, isoutbound, f, ast, 1);
else {
ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast->name);
res = 0;
@@ -367,7 +370,7 @@ static int local_indicate(struct ast_channel *ast, int condition, const void *da
f.subclass = condition;
f.data = (void*)data;
f.datalen = datalen;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
+ if (!(res = local_queue_frame(p, isoutbound, &f, ast, 1)))
ast_mutex_unlock(&p->lock);
}
@@ -387,7 +390,7 @@ static int local_digit_begin(struct ast_channel *ast, char digit)
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = digit;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
+ if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
ast_mutex_unlock(&p->lock);
return res;
@@ -407,7 +410,7 @@ static int local_digit_end(struct ast_channel *ast, char digit, unsigned int dur
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = digit;
f.len = duration;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
+ if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
ast_mutex_unlock(&p->lock);
return res;
@@ -427,7 +430,7 @@ static int local_sendtext(struct ast_channel *ast, const char *text)
isoutbound = IS_OUTBOUND(ast, p);
f.data = (char *) text;
f.datalen = strlen(text) + 1;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
+ if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
ast_mutex_unlock(&p->lock);
return res;
}
@@ -447,7 +450,7 @@ static int local_sendhtml(struct ast_channel *ast, int subclass, const char *dat
f.subclass = subclass;
f.data = (char *)data;
f.datalen = datalen;
- if (!(res = local_queue_frame(p, isoutbound, &f, ast)))
+ if (!(res = local_queue_frame(p, isoutbound, &f, ast, 0)))
ast_mutex_unlock(&p->lock);
return res;
}
@@ -572,7 +575,7 @@ static int local_hangup(struct ast_channel *ast)
/* Need to actually hangup since there is no PBX */
ochan = p->chan;
else
- res = local_queue_frame(p, isoutbound, &f, NULL);
+ res = local_queue_frame(p, isoutbound, &f, NULL, 1);
if (!res)
ast_mutex_unlock(&p->lock);
if (ochan)