Fix incorrect calls to ast_bridge_impart().
authorRichard Mudgett <rmudgett@digium.com>
Wed, 26 Jun 2013 01:46:30 +0000 (01:46 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 26 Jun 2013 01:46:30 +0000 (01:46 +0000)
There was a misunderstanding about ast_bridge_impart()'s handling of the
imparted channel's reference.  The channel reference is passed by the
caller unless ast_bridge_impart() returns an error.

* Fixed a memory leak in conf_announce_channel_push() if the impart
failed.

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

apps/confbridge/conf_chan_announce.c
channels/chan_sip.c
include/asterisk/bridging.h

index 46e074b..af96884 100644 (file)
@@ -172,8 +172,8 @@ void conf_announce_channel_depart(struct ast_channel *chan)
 int conf_announce_channel_push(struct ast_channel *ast)
 {
        struct ast_bridge_features *features;
 int conf_announce_channel_push(struct ast_channel *ast)
 {
        struct ast_bridge_features *features;
+       struct ast_channel *chan;
        RAII_VAR(struct announce_pvt *, p, NULL, ao2_cleanup);
        RAII_VAR(struct announce_pvt *, p, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_unref);
 
        {
                SCOPED_CHANNELLOCK(lock, ast);
 
        {
                SCOPED_CHANNELLOCK(lock, ast);
@@ -192,12 +192,15 @@ int conf_announce_channel_push(struct ast_channel *ast)
 
        features = ast_bridge_features_new();
        if (!features) {
 
        features = ast_bridge_features_new();
        if (!features) {
+               ast_channel_unref(chan);
                return -1;
        }
        ast_set_flag(&features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
 
        /* Impart the output channel into the bridge */
        if (ast_bridge_impart(p->bridge, chan, NULL, features, 0)) {
                return -1;
        }
        ast_set_flag(&features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
 
        /* Impart the output channel into the bridge */
        if (ast_bridge_impart(p->bridge, chan, NULL, features, 0)) {
+               ast_bridge_features_destroy(features);
+               ast_channel_unref(chan);
                return -1;
        }
        ao2_lock(p);
                return -1;
        }
        ao2_lock(p);
index 689b43a..916fd5e 100644 (file)
@@ -24777,8 +24777,8 @@ static int handle_request_options(struct sip_pvt *p, struct sip_request *req, st
 static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req,
                int *nounlock, struct sip_pvt *replaces_pvt, struct ast_channel *replaces_chan)
 {
 static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req,
                int *nounlock, struct sip_pvt *replaces_pvt, struct ast_channel *replaces_chan)
 {
+       struct ast_channel *c;
        RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
        RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_channel *, c, NULL, ao2_cleanup);
 
        if (req->ignore) {
                return 0;
 
        if (req->ignore) {
                return 0;
@@ -24813,7 +24813,9 @@ static int handle_invite_replaces(struct sip_pvt *p, struct sip_request *req,
        ast_channel_unlock(replaces_chan);
 
        if (bridge) {
        ast_channel_unlock(replaces_chan);
 
        if (bridge) {
-               ast_bridge_impart(bridge, c, replaces_chan, NULL, 1);
+               if (ast_bridge_impart(bridge, c, replaces_chan, NULL, 1)) {
+                       ast_hangup(c);
+               }
        } else {
                ast_channel_move(replaces_chan, c);
                ast_hangup(c);
        } else {
                ast_channel_move(replaces_chan, c);
                ast_hangup(c);
index 8502458..6e6d73b 100644 (file)
@@ -654,7 +654,7 @@ enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge,
  * \brief Impart (non-blocking) a channel onto a bridge
  *
  * \param bridge Bridge to impart on
  * \brief Impart (non-blocking) a channel onto a bridge
  *
  * \param bridge Bridge to impart on
- * \param chan Channel to impart
+ * \param chan Channel to impart (The channel reference is stolen if impart successful.)
  * \param swap Channel to swap out if swapping.  NULL if not swapping.
  * \param features Bridge features structure.
  * \param independent TRUE if caller does not want to reclaim the channel using ast_bridge_depart().
  * \param swap Channel to swap out if swapping.  NULL if not swapping.
  * \param features Bridge features structure.
  * \param independent TRUE if caller does not want to reclaim the channel using ast_bridge_depart().