Make chan_local module references tied to local_pvt lifetime.

The chan_local module references were manually tied to the existence of
the ;1 and ;2 channel links.

* Made chan_local module references tied to the existence of the local_pvt
structure as well as automatically take care of the module references.

* Tweaked the wording of the local_fixup() failure warning message to make
sense.

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


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@378088 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/98/198/1
Richard Mudgett 13 years ago
parent c75a2efd1b
commit 7700095727

@ -151,8 +151,6 @@ struct local_pvt {
struct ast_jb_conf jb_conf; /*!< jitterbuffer configuration for this local channel */
struct ast_channel *owner; /*!< Master Channel - Bridging happens here */
struct ast_channel *chan; /*!< Outbound channel - PBX is run here */
struct ast_module_user *u_owner; /*!< reference to keep the module loaded while in use */
struct ast_module_user *u_chan; /*!< reference to keep the module loaded while in use */
};
#define LOCAL_ALREADY_MASQED (1 << 0) /*!< Already masqueraded */
@ -578,6 +576,7 @@ static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
}
if (p->chan->audiohooks) {
struct ast_audiohook_list *audiohooks_swapper;
audiohooks_swapper = p->chan->audiohooks;
p->chan->audiohooks = p->owner->audiohooks;
p->owner->audiohooks = audiohooks_swapper;
@ -679,7 +678,7 @@ static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
ao2_lock(p);
if ((p->owner != oldchan) && (p->chan != oldchan)) {
ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
ao2_unlock(p);
return -1;
}
@ -1047,16 +1046,15 @@ static int local_hangup(struct ast_channel *ast)
if (isoutbound) {
const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
if ((status) && (p->owner)) {
if (status && p->owner) {
p->owner->hangupcause = p->chan->hangupcause;
pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
}
ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
ast_module_user_remove(p->u_chan);
p->chan = NULL;
} else {
ast_module_user_remove(p->u_owner);
if (p->chan) {
ast_queue_hangup(p->chan);
}
@ -1067,6 +1065,7 @@ static int local_hangup(struct ast_channel *ast)
if (!p->owner && !p->chan) {
ao2_unlock(p);
/* Remove from list */
ao2_unlink(locals, p);
ao2_ref(p, -1);
@ -1086,6 +1085,10 @@ local_hangup_cleanup:
ao2_unlock(p);
ao2_ref(p, -1);
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
if (chan) {
ast_channel_unlock(chan);
if (hangup_chan) {
@ -1093,26 +1096,37 @@ local_hangup_cleanup:
}
chan = ast_channel_unref(chan);
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
/* leave with the same stupid channel locked that came in */
ast_channel_lock(ast);
return res;
}
/*!
* \internal
* \brief struct local_pvt destructor.
*
* \param vdoomed Void local_pvt to destroy.
*
* \return Nothing
*/
static void local_pvt_destructor(void *vdoomed)
{
ast_module_unref(ast_module_info->self);
}
/*! \brief Create a call structure */
static struct local_pvt *local_alloc(const char *data, format_t format)
{
struct local_pvt *tmp = NULL;
char *c = NULL, *opts = NULL;
if (!(tmp = ao2_alloc(sizeof(*tmp), NULL))) {
if (!(tmp = ao2_alloc(sizeof(*tmp), local_pvt_destructor))) {
return NULL;
}
ast_module_ref(ast_module_info->self);
/* Initialize private structure information */
ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
@ -1217,8 +1231,6 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
p->owner = tmp;
p->chan = tmp2;
p->u_owner = ast_module_user_add(p->owner);
p->u_chan = ast_module_user_add(p->chan);
ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
@ -1248,9 +1260,7 @@ static struct ast_channel *local_request(const char *type, format_t format, cons
} else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
ao2_unlink(locals, p);
p->owner = ast_channel_release(p->owner);
ast_module_user_remove(p->u_owner);
p->chan = ast_channel_release(p->chan);
ast_module_user_remove(p->u_chan);
chan = NULL;
}
ao2_ref(p, -1); /* kill the ref from the alloc */

Loading…
Cancel
Save