Add any missing locking calls
authorMark Spencer <markster@digium.com>
Wed, 13 Aug 2003 17:32:44 +0000 (17:32 +0000)
committerMark Spencer <markster@digium.com>
Wed, 13 Aug 2003 17:32:44 +0000 (17:32 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1312 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
channel.c
channels/chan_agent.c
channels/chan_local.c

diff --git a/CHANGES b/CHANGES
index 16c88e5..60da7c9 100755 (executable)
--- 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
index c393631..81f3a66 100755 (executable)
--- 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);
index 74155d0..3075643 100755 (executable)
@@ -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);
index 7889d0f..9b60a02 100755 (executable)
@@ -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 */