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
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 ast_channel *, chan, NULL, ast_channel_unref);
{
SCOPED_CHANNELLOCK(lock, ast);
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)) {
+ ast_bridge_features_destroy(features);
+ ast_channel_unref(chan);
return -1;
}
ao2_lock(p);
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_channel *, c, NULL, ao2_cleanup);
if (req->ignore) {
return 0;
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);
* \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().