]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
automerge commit
authorAutomerge script <automerge@asterisk.org>
Mon, 10 Jul 2006 22:02:08 +0000 (22:02 +0000)
committerAutomerge script <automerge@asterisk.org>
Mon, 10 Jul 2006 22:02:08 +0000 (22:02 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@37375 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channel.c

index 1f5f5960523955b2decfc2609b7e0baacf7c99a2..dc33e8a573284b53d529bbc227eb10a1273e90ac 100644 (file)
--- a/channel.c
+++ b/channel.c
@@ -2748,25 +2748,43 @@ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clo
 {
        struct ast_frame null = { AST_FRAME_NULL, };
        int res = -1;
+       struct ast_channel *final_orig = original, *final_clone = clone;
+
+       ast_mutex_lock(&original->lock);
+       while(ast_mutex_trylock(&clone->lock)) {
+               ast_mutex_unlock(&original->lock);
+               usleep(1);
+               ast_mutex_lock(&original->lock);
+       }
 
        /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
           and if so, we don't really want to masquerade it, but its proxy */
        if (original->_bridge && (original->_bridge != ast_bridged_channel(original)))
-               original = original->_bridge;
+               final_orig = original->_bridge;
 
        if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)))
-               clone = clone->_bridge;
+               final_clone = clone->_bridge;
+
+       if ((final_orig != original) || (final_clone != clone)) {
+               ast_mutex_lock(&final_orig->lock);
+               while(ast_mutex_trylock(&final_clone->lock)) {
+                       ast_mutex_unlock(&final_orig->lock);
+                       usleep(1);
+                       ast_mutex_lock(&final_orig->lock);
+               }
+               ast_mutex_unlock(&clone->lock);
+               ast_mutex_unlock(&original->lock);
+               original = final_orig;
+               clone = final_clone;
+       }
 
        if (original == clone) {
                ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
-               return -1;
-       }
-       ast_mutex_lock(&original->lock);
-       while(ast_mutex_trylock(&clone->lock)) {
+               ast_mutex_unlock(&clone->lock);
                ast_mutex_unlock(&original->lock);
-               usleep(1);
-               ast_mutex_lock(&original->lock);
+               return -1;
        }
+
        ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
                clone->name, original->name);
        if (original->masq) {
@@ -2783,8 +2801,10 @@ int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clo
                ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
                res = 0;
        }
+
        ast_mutex_unlock(&clone->lock);
        ast_mutex_unlock(&original->lock);
+
        return res;
 }