aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-08-13 17:32:44 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-08-13 17:32:44 +0000
commitbd0679195f59fd5ef7d94aea54011912c0b316fc (patch)
tree97db604054b44caec1b496f9dcf1813cd55c2343
parent00f52a9872a88a380a800771b881f652f6f4126f (diff)
Add any missing locking calls
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@1312 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xCHANGES1
-rwxr-xr-xchannel.c2
-rwxr-xr-xchannels/chan_agent.c47
-rwxr-xr-xchannels/chan_local.c9
4 files changed, 45 insertions, 14 deletions
diff --git a/CHANGES b/CHANGES
index 16c88e52f..60da7c975 100755
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,4 @@
+ -- Add thread debugging
-- Add optional pedantic SIP checking for Pingtel
-- Allow extension names, include context, switch to use global vars.
-- Allow variables in extensions.conf to reference previously defined ones
diff --git a/channel.c b/channel.c
index c39363179..81f3a6660 100755
--- a/channel.c
+++ b/channel.c
@@ -704,8 +704,10 @@ int ast_answer(struct ast_channel *chan)
switch(chan->_state) {
case AST_STATE_RINGING:
case AST_STATE_RING:
+ ast_mutex_lock(&chan->lock);
if (chan->pvt->answer)
res = chan->pvt->answer(chan);
+ ast_mutex_unlock(&chan->lock);
ast_setstate(chan, AST_STATE_UP);
if (chan->cdr)
ast_cdr_answer(chan->cdr);
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index 74155d0a8..307564329 100755
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -111,6 +111,23 @@ static struct agent_pvt {
struct agent_pvt *next; /* Agent */
} *agents = NULL;
+#define CHECK_FORMATS(ast, p) do { \
+ if (p->chan) {\
+ if (ast->nativeformats != p->chan->nativeformats) { \
+ ast_log(LOG_DEBUG, "Native formats changing from %d to %d\n", ast->nativeformats, p->chan->nativeformats); \
+ /* Native formats changed, reset things */ \
+ ast->nativeformats = p->chan->nativeformats; \
+ ast_log(LOG_DEBUG, "Resetting read to %d and write to %d\n", ast->readformat, ast->writeformat);\
+ ast_set_read_format(ast, ast->readformat); \
+ ast_set_write_format(ast, ast->writeformat); \
+ } \
+ if (p->chan->readformat != ast->pvt->rawreadformat) \
+ ast_set_read_format(p->chan, ast->pvt->rawreadformat); \
+ if (p->chan->writeformat != ast->pvt->rawwriteformat) \
+ ast_set_write_format(p->chan, ast->pvt->rawwriteformat); \
+ } \
+} while(0)
+
#define CLEANUP(ast, p) do { \
int x; \
if (p->chan) { \
@@ -227,8 +244,8 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
static struct ast_frame null_frame = { AST_FRAME_NULL, };
static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
ast_mutex_lock(&p->lock);
+ CHECK_FORMATS(ast, p);
if (p->chan) {
- p->chan->pvt->rawreadformat = ast->pvt->rawreadformat;
f = ast_read(p->chan);
} else
f = &null_frame;
@@ -243,16 +260,16 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
}
if (f && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
/* TC */
- if (p->ackcall) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s answered, waiting for '#' to acknowledge\n", p->chan->name);
- /* Don't pass answer along */
- ast_frfree(f);
- f = &null_frame;
- }
+ if (p->ackcall) {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s answered, waiting for '#' to acknowledge\n", p->chan->name);
+ /* Don't pass answer along */
+ ast_frfree(f);
+ f = &null_frame;
+ }
else {
- p->acknowledged = 1;
- f = &answer_frame;
+ p->acknowledged = 1;
+ f = &answer_frame;
}
}
if (f && (f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
@@ -278,10 +295,16 @@ static int agent_write(struct ast_channel *ast, struct ast_frame *f)
{
struct agent_pvt *p = ast->pvt->pvt;
int res = -1;
+ CHECK_FORMATS(ast, p);
ast_mutex_lock(&p->lock);
if (p->chan) {
- p->chan->pvt->rawwriteformat = ast->pvt->rawwriteformat;
- res = ast_write(p->chan, f);
+ if ((f->frametype != AST_FRAME_VOICE) ||
+ (f->subclass == p->chan->writeformat)) {
+ res = ast_write(p->chan, f);
+ } else {
+ ast_log(LOG_DEBUG, "Dropping one incompatible voice frame on '%s' to '%s'\n", ast->name, p->chan->name);
+ res = 0;
+ }
} else
res = 0;
CLEANUP(ast, p);
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 7889d0fa3..9b60a0263 100755
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -91,8 +91,13 @@ retrylock:
if (ast_mutex_trylock(&other->lock)) {
/* Failed to lock. Release main lock and try again */
ast_mutex_unlock(&p->lock);
- if (us)
- ast_mutex_unlock(&us->lock);
+ if (us) {
+ if (ast_mutex_unlock(&us->lock)) {
+ ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
+ us->name, f->frametype, f->subclass);
+ us = NULL;
+ }
+ }
/* Wait just a bit */
usleep(1);
/* Only we can destroy ourselves, so we can't disappear here */