Merge "stasis: Fix dial masquerade datastore lifetime"

changes/66/366/1
Matt Jordan 10 years ago committed by Gerrit Code Review
commit bc8dcbdfbc

@ -364,6 +364,7 @@ static void ast_channel_publish_dial_internal(struct ast_channel *caller,
}
static void remove_dial_masquerade(struct ast_channel *peer);
static void remove_dial_masquerade_caller(struct ast_channel *caller);
static int set_dial_masquerade(struct ast_channel *caller,
struct ast_channel *peer, const char *dialstring);
@ -373,6 +374,11 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha
{
ast_assert(peer != NULL);
/* XXX With an early bridge the below dial masquerade datastore code could, theoretically,
* go away as the act of changing the channel during dialing would be done using the bridge
* API itself and not a masquerade.
*/
if (caller) {
/*
* Lock two or three channels.
@ -407,6 +413,7 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha
ast_channel_unlock(forwarded);
}
ast_channel_unlock(peer);
remove_dial_masquerade_caller(caller);
ast_channel_unlock(caller);
}
}
@ -1349,7 +1356,6 @@ static void dial_masquerade_datastore_cleanup(struct dial_masquerade_datastore *
while ((cur = AST_LIST_REMOVE_HEAD(&masq_data->dialed_peers, list))) {
dial_target_free(cur);
}
masq_data->caller = ast_channel_cleanup(masq_data->caller);
}
static void dial_masquerade_datastore_remove_chan(struct dial_masquerade_datastore *masq_data, struct ast_channel *chan)
@ -1399,6 +1405,16 @@ static void dial_masquerade_datastore_destroy(void *data)
ao2_ref(data, -1);
}
/*!
* \internal
* \brief Datastore destructor for dial_masquerade_datastore
*/
static void dial_masquerade_caller_datastore_destroy(void *data)
{
dial_masquerade_datastore_cleanup(data);
ao2_ref(data, -1);
}
static struct ast_datastore *dial_masquerade_datastore_find(struct ast_channel *chan);
static void dial_masquerade_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
@ -1517,6 +1533,13 @@ static const struct ast_datastore_info dial_masquerade_info = {
.chan_breakdown = dial_masquerade_breakdown,
};
static const struct ast_datastore_info dial_masquerade_caller_info = {
.type = "stasis-chan-dial-masq",
.destroy = dial_masquerade_caller_datastore_destroy,
.chan_fixup = dial_masquerade_fixup,
.chan_breakdown = dial_masquerade_breakdown,
};
/*!
* \internal
* \brief Find the dial masquerade datastore on the given channel.
@ -1527,7 +1550,14 @@ static const struct ast_datastore_info dial_masquerade_info = {
*/
static struct ast_datastore *dial_masquerade_datastore_find(struct ast_channel *chan)
{
return ast_channel_datastore_find(chan, &dial_masquerade_info, NULL);
struct ast_datastore *datastore;
datastore = ast_channel_datastore_find(chan, &dial_masquerade_info, NULL);
if (!datastore) {
datastore = ast_channel_datastore_find(chan, &dial_masquerade_caller_info, NULL);
}
return datastore;
}
/*!
@ -1546,7 +1576,7 @@ static struct dial_masquerade_datastore *dial_masquerade_datastore_add(
{
struct ast_datastore *datastore;
datastore = ast_datastore_alloc(&dial_masquerade_info, NULL);
datastore = ast_datastore_alloc(!masq_data ? &dial_masquerade_caller_info : &dial_masquerade_info, NULL);
if (!datastore) {
return NULL;
}
@ -1557,7 +1587,7 @@ static struct dial_masquerade_datastore *dial_masquerade_datastore_add(
ast_datastore_free(datastore);
return NULL;
}
masq_data->caller = ast_channel_ref(chan);
masq_data->caller = chan;
}
datastore->data = masq_data;
@ -1663,3 +1693,24 @@ static void remove_dial_masquerade(struct ast_channel *peer)
ast_channel_datastore_remove(peer, datastore);
ast_datastore_free(datastore);
}
static void remove_dial_masquerade_caller(struct ast_channel *caller)
{
struct ast_datastore *datastore;
struct dial_masquerade_datastore *masq_data;
datastore = dial_masquerade_datastore_find(caller);
if (!datastore) {
return;
}
masq_data = datastore->data;
if (!masq_data || !AST_LIST_EMPTY(&masq_data->dialed_peers)) {
return;
}
dial_masquerade_datastore_remove_chan(masq_data, caller);
ast_channel_datastore_remove(caller, datastore);
ast_datastore_free(datastore);
}

Loading…
Cancel
Save