Author: rmudgett
Date: Mon Oct  6 10:38:42 2014
New Revision: 424669

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=424669
Log:
features.c: Fix lingering channel ref while Bridge() application is active.

Using the Bridge application to bridge a channel that is executing an
applicaiton such as Wait results in a lingering Surrogate channel in the
CLI "core show channels" output even though it has already hungup.

* Fix bridge_exec() to not hold onto the current_dest_chan ref once it has
been put into the bridge.

* Eliminated bridge_exec()'s use of RAII_VAR().

ASTERISK-24224 #close
Reported by: Mark Michelson

Review: https://reviewboard.asterisk.org/r/4041/
........

Merged revisions 424668 from http://svn.asterisk.org/svn/asterisk/branches/12

Modified:
    branches/13/   (props changed)
    branches/13/main/features.c

Propchange: branches/13/
------------------------------------------------------------------------------
Binary property 'branch-12-merged' - no diff available.

Modified: branches/13/main/features.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/13/main/features.c?view=diff&rev=424669&r1=424668&r2=424669
==============================================================================
--- branches/13/main/features.c (original)
+++ branches/13/main/features.c Mon Oct  6 10:38:42 2014
@@ -1013,7 +1013,7 @@
  */
 static int bridge_exec(struct ast_channel *chan, const char *data)
 {
-       RAII_VAR(struct ast_channel *, current_dest_chan, NULL, ao2_cleanup);
+       struct ast_channel *current_dest_chan;
        char *tmp_data  = NULL;
        struct ast_flags opts = { 0, };
        struct ast_bridge_config bconfig = { { 0, }, };
@@ -1022,10 +1022,11 @@
        const char *context;
        const char *extension;
        int priority;
+       int bridge_add_failed;
        struct ast_bridge_features chan_features;
        struct ast_bridge_features *peer_features;
        struct ast_bridge *bridge;
-       RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, 
ao2_cleanup);
+       struct ast_features_xfer_config *xfer_cfg;
 
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(dest_chan);
@@ -1043,8 +1044,9 @@
                ast_app_parse_options(bridge_exec_options, &opts, opt_args, 
args.options);
 
        /* make sure we have a valid end point */
-       if (!(current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
-                       strlen(args.dest_chan)))) {
+       current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
+               strlen(args.dest_chan));
+       if (!current_dest_chan) {
                ast_log(LOG_WARNING, "Bridge failed because channel %s does not 
exist\n",
                        args.dest_chan);
                return 0;
@@ -1052,6 +1054,7 @@
 
        /* avoid bridge with ourselves */
        if (chan == current_dest_chan) {
+               ast_channel_unref(current_dest_chan);
                ast_log(LOG_WARNING, "Unable to bridge channel %s with 
itself\n", ast_channel_name(chan));
                return 0;
        }
@@ -1123,13 +1126,19 @@
        }
 
        xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan);
-       if (ast_bridge_add_channel(bridge, current_dest_chan, peer_features,
-               ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE), xfer_cfg ? 
xfer_cfg->xfersound : NULL)) {
+       bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, 
peer_features,
+               ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE),
+               xfer_cfg ? xfer_cfg->xfersound : NULL);
+       ao2_cleanup(xfer_cfg);
+       if (bridge_add_failed) {
                ast_bridge_features_destroy(peer_features);
                ast_bridge_features_cleanup(&chan_features);
                ast_bridge_destroy(bridge, 0);
                goto done;
        }
+
+       /* Don't keep the channel ref in case it was not already in a bridge. */
+       current_dest_chan = ast_channel_unref(current_dest_chan);
 
        ast_bridge_join(bridge, chan, NULL, &chan_features, NULL,
                AST_BRIDGE_JOIN_PASS_REFERENCE);
@@ -1143,6 +1152,7 @@
        ast_free((char *) bconfig.end_sound);
        ast_free((char *) bconfig.start_sound);
 
+       ast_channel_cleanup(current_dest_chan);
        return 0;
 }
 


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to