]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Simplify locking code for REDIRECTING interception macro when forwarding a call.
authorRichard Mudgett <rmudgett@digium.com>
Tue, 21 Sep 2010 20:29:59 +0000 (20:29 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Tue, 21 Sep 2010 20:29:59 +0000 (20:29 +0000)
Simplified the locking code by using a local copy of the redirecting party
information in app_dial.c:do_forward() and app_queue.c:wait_for_answer()
for launching the REDIRECTING interception macro when a call is forwarded.

Reduced the lock time of the 'o->chan' and 'in' channels.

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@288080 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_dial.c
apps/app_queue.c

index 0f7b4880d00205b5f0514aa5deb8fff028a87477..51dacb6db96b294949c3e0d8ed729fe3695fd6ac 100644 (file)
@@ -852,6 +852,8 @@ static void do_forward(struct chanlist *o,
                handle_cause(cause, num);
                ast_hangup(original);
        } else {
+               struct ast_party_redirecting redirecting;
+
                if (single && CAN_EARLY_BRIDGE(peerflags, c, in)) {
                        ast_rtp_instance_early_bridge_make_compatible(c, in);
                }
@@ -895,22 +897,20 @@ static void do_forward(struct chanlist *o,
                 * deadlock. This is why the handling of c's lock may seem a bit unusual
                 * here.
                 */
+               ast_party_redirecting_init(&redirecting);
+               ast_party_redirecting_copy(&redirecting, &c->redirecting);
                ast_channel_unlock(c);
-               if (ast_channel_redirecting_macro(c, in, &c->redirecting, 1, 0)) {
-                       while (ast_channel_trylock(c)) {
-                               CHANNEL_DEADLOCK_AVOIDANCE(in);
-                       }
-                       ast_channel_update_redirecting(in, &c->redirecting, NULL);
-                       ast_channel_unlock(c);
+               if (ast_channel_redirecting_macro(c, in, &redirecting, 1, 0)) {
+                       ast_channel_update_redirecting(in, &redirecting, NULL);
                }
+               ast_party_redirecting_free(&redirecting);
+               ast_channel_unlock(in);
 
                ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE);
                if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
                        *to = -1;
                }
 
-               ast_channel_unlock(in);
-
                if (ast_call(c, stuff, 0)) {
                        ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
                                tech, stuff);
index f44f2152a64e6b753c253ca0ed692506615f815e..e6ce9495b585320d8b64c2d53b9ee2b7760657eb 100644 (file)
@@ -3414,6 +3414,8 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
                                                o->stillgoing = 0;
                                                numnochan++;
                                        } else {
+                                               struct ast_party_redirecting redirecting;
+
                                                ast_channel_lock(o->chan);
                                                while (ast_channel_trylock(in)) {
                                                        CHANNEL_DEADLOCK_AVOIDANCE(o->chan);
@@ -3449,27 +3451,24 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
                                                 * deadlock.  This is why the handling of o->chan's lock may
                                                 * seem a bit unusual here.
                                                 */
+                                               ast_party_redirecting_init(&redirecting);
+                                               ast_party_redirecting_copy(&redirecting, &o->chan->redirecting);
                                                ast_channel_unlock(o->chan);
-                                               res = ast_channel_redirecting_macro(o->chan, in, &o->chan->redirecting, 1, 0);
-                                               while (ast_channel_trylock(o->chan)) {
-                                                       CHANNEL_DEADLOCK_AVOIDANCE(in);
-                                               }
+                                               res = ast_channel_redirecting_macro(o->chan, in, &redirecting, 1, 0);
                                                if (res) {
-                                                       ast_channel_update_redirecting(in, &o->chan->redirecting, NULL);
+                                                       ast_channel_update_redirecting(in, &redirecting, NULL);
                                                }
+                                               ast_party_redirecting_free(&redirecting);
+                                               ast_channel_unlock(in);
 
                                                update_connectedline = 1;
 
                                                if (ast_call(o->chan, stuff, 0)) {
                                                        ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n",
                                                                tech, stuff);
-                                                       ast_channel_unlock(o->chan);
                                                        do_hang(o);
                                                        numnochan++;
-                                               } else {
-                                                       ast_channel_unlock(o->chan);
                                                }
-                                               ast_channel_unlock(in);
                                        }
                                        /* Hangup the original channel now, in case we needed it */
                                        ast_hangup(winner);