[asterisk-commits] russell: branch russell/chan_refcount r82333 - /team/russell/chan_refcount/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Sep 13 12:58:06 CDT 2007
Author: russell
Date: Thu Sep 13 12:58:05 2007
New Revision: 82333
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82333
Log:
convert res_features to use new channel find/iterate functions
Modified:
team/russell/chan_refcount/res/res_features.c
Modified: team/russell/chan_refcount/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/res/res_features.c?view=diff&rev=82333&r1=82332&r2=82333
==============================================================================
--- team/russell/chan_refcount/res/res_features.c (original)
+++ team/russell/chan_refcount/res/res_features.c Thu Sep 13 12:58:05 2007
@@ -2421,18 +2421,19 @@
*/
static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
{
+ ast_channel_lock_both(chan, tmpchan);
+
ast_moh_stop(chan);
- ast_mutex_lock(&chan->lock);
ast_setstate(tmpchan, chan->_state);
tmpchan->readformat = chan->readformat;
tmpchan->writeformat = chan->writeformat;
ast_channel_masquerade(tmpchan, chan);
- ast_mutex_lock(&tmpchan->lock);
ast_do_masquerade(tmpchan);
/* when returning from bridge, the channel will continue at the next priority */
ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
- ast_mutex_unlock(&tmpchan->lock);
- ast_mutex_unlock(&chan->lock);
+
+ ast_channel_unlock(chan);
+ ast_channel_unlock(tmpchan);
}
/*!
@@ -2457,52 +2458,55 @@
struct ast_channel *chana = NULL, *chanb = NULL;
struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
struct ast_bridge_thread_obj *tobj = NULL;
+ const char *err_msg = NULL;
+ int res = 0;
/* make sure valid channels were specified */
- if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
- chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
- chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
- if (chana)
- ast_mutex_unlock(&chana->lock);
- if (chanb)
- ast_mutex_unlock(&chanb->lock);
-
- /* send errors if any of the channels could not be found/locked */
- if (!chana) {
- char buf[256];
- snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela);
- astman_send_error(s, m, buf);
- return 0;
- }
- if (!chanb) {
- char buf[256];
- snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
- astman_send_error(s, m, buf);
- return 0;
- }
- } else {
+ if (ast_strlen_zero(channela) || ast_strlen_zero(channelb)) {
astman_send_error(s, m, "Missing channel parameter in request");
return 0;
}
- /* Answer the channels if needed */
+ if (!(chana = ast_channel_get_by_name_prefix(channela, strlen(channela)))) {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "Channel1 does not exists: %s", channela);
+ astman_send_error(s, m, buf);
+
+ return 0;
+ }
+
+ if (!(chanb = ast_channel_get_by_name_prefix(channelb, strlen(channelb)))) {
+ char buf[256];
+
+ ast_channel_unref(chana);
+
+ snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
+ astman_send_error(s, m, buf);
+
+ return 0;
+ }
+
if (chana->_state != AST_STATE_UP)
ast_answer(chana);
+
if (chanb->_state != AST_STATE_UP)
ast_answer(chanb);
/* create the placeholder channels and grab the other channels */
if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
NULL, NULL, 0, "Bridge/%s", chana->name))) {
- astman_send_error(s, m, "Unable to create temporary channel!");
- return 1;
+ err_msg = "Unable to create temporary channel!";
+ res = 1;
+ goto return_cleanup;
}
if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
NULL, NULL, 0, "Bridge/%s", chanb->name))) {
- astman_send_error(s, m, "Unable to create temporary channels!");
+ err_msg = "Unable to create temporary channel!";
ast_channel_free(tmpchana);
- return 1;
+ res = 1;
+ goto return_cleanup;
}
do_bridge_masquerade(chana, tmpchana);
@@ -2511,19 +2515,21 @@
/* make the channels compatible, send error if we fail doing so */
if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
- astman_send_error(s, m, "Could not make channels compatible for manager bridge");
+ err_msg = "Could not make channels compatible for manager bridge";
ast_hangup(tmpchana);
ast_hangup(tmpchanb);
- return 1;
+ res = 1;
+ goto return_cleanup;
}
/* setup the bridge thread object and start the bridge */
if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
- astman_send_error(s, m, "Unable to spawn a new bridge thread");
+ err_msg = "Unable to spawn a new bridge thread";
ast_hangup(tmpchana);
ast_hangup(tmpchanb);
- return 1;
+ res = 1;
+ goto return_cleanup;
}
tobj->chan = tmpchana;
@@ -2541,7 +2547,14 @@
astman_send_ack(s, m, "Launched bridge thread with success");
- return 0;
+return_cleanup:
+ ast_channel_unref(chana);
+ ast_channel_unref(chanb);
+
+ if (err_msg)
+ astman_send_error(s, m, err_msg);
+
+ return res;
}
static char showfeatures_help[] =
@@ -2698,24 +2711,23 @@
return 0;
}
- ch1 = ast_get_channel_by_name_locked(channel);
- if (!ch1) {
+ if (!(ch1 = ast_channel_get_by_name(channel))) {
snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
astman_send_error(s, m, buf);
return 0;
}
- ch2 = ast_get_channel_by_name_locked(channel2);
- if (!ch2) {
+ if (!(ch2 = ast_channel_get_by_name(channel2))) {
+ ast_channel_unref(ch1);
snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel2);
astman_send_error(s, m, buf);
- ast_channel_unlock(ch1);
return 0;
}
- if (!ast_strlen_zero(timeout)) {
+ if (!ast_strlen_zero(timeout))
sscanf(timeout, "%d", &to);
- }
+
+ ast_channel_lock_both(ch1, ch2);
res = ast_masq_park_call(ch1, ch2, to, &parkExt);
if (!res) {
@@ -2727,6 +2739,9 @@
ast_channel_unlock(ch1);
ast_channel_unlock(ch2);
+
+ ast_channel_unref(ch1);
+ ast_channel_unref(ch2);
return 0;
}
@@ -2743,17 +2758,25 @@
{
struct ast_channel *cur = NULL;
int res = -1;
-
- while ((cur = ast_channel_walk_locked(cur)) != NULL) {
+ struct ast_channel_iterator *iter;
+
+ if (!(iter = ast_channel_iterator_all_new()))
+ return -1;
+
+ while ((cur = ast_channel_iterator_next(iter))) {
+ ast_channel_lock(cur);
if (!cur->pbx &&
(cur != chan) &&
(chan->pickupgroup & cur->callgroup) &&
((cur->_state == AST_STATE_RINGING) ||
(cur->_state == AST_STATE_RING))) {
+ ast_channel_unlock(cur);
break;
}
ast_channel_unlock(cur);
- }
+ ast_channel_unref(cur);
+ }
+
if (cur) {
ast_debug(1, "Call pickup on chan '%s' by '%s'\n",cur->name, chan->name);
res = ast_answer(chan);
@@ -2765,10 +2788,11 @@
res = ast_channel_masquerade(cur, chan);
if (res)
ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, cur->name); /* Done */
- ast_channel_unlock(cur);
+ ast_channel_unref(cur);
} else {
ast_debug(1, "No call pickup possible...\n");
}
+
return res;
}
@@ -3151,7 +3175,7 @@
}
/* make sure we have a valid end point */
- if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan,
+ if (!(current_dest_chan = ast_channel_get_by_name_prefix(args.dest_chan,
strlen(args.dest_chan)))) {
ast_log(LOG_WARNING, "Bridge failed because channel %s does not exists or we "
"cannot get its lock\n", args.dest_chan);
@@ -3164,7 +3188,6 @@
ast_module_user_remove(u);
return 0;
}
- ast_mutex_unlock(¤t_dest_chan->lock);
/* answer the channel if needed */
if (current_dest_chan->_state != AST_STATE_UP)
@@ -3179,11 +3202,22 @@
"Reason: cannot create placeholder\r\n"
"Channel1: %s\r\n"
"Channel2: %s\r\n", chan->name, args.dest_chan);
- }
+ ast_hangup(current_dest_chan);
+ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
+ ast_module_user_remove(u);
+ return 0;
+ }
+
+ ast_channel_lock_both(current_dest_chan, final_dest_chan);
do_bridge_masquerade(current_dest_chan, final_dest_chan);
+ ast_channel_unlock(final_dest_chan);
+ ast_channel_unlock(current_dest_chan);
+ current_dest_chan = ast_channel_unref(current_dest_chan);
+
/* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
/* try to make compatible, send error if we fail */
+ ast_channel_lock(final_dest_chan);
if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
manager_event(EVENT_FLAG_CALL, "BridgeExec",
@@ -3191,6 +3225,7 @@
"Reason: Could not make channels compatible for bridge\r\n"
"Channel1: %s\r\n"
"Channel2: %s\r\n", chan->name, final_dest_chan->name);
+ ast_channel_unlock(final_dest_chan);
ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
ast_module_user_remove(u);
@@ -3210,7 +3245,9 @@
ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
}
}
-
+
+ ast_channel_unlock(final_dest_chan);
+
/* do the bridge */
ast_bridge_call(chan, final_dest_chan, &bconfig);
@@ -3226,6 +3263,8 @@
ast_hangup(final_dest_chan);
} else
ast_debug(1, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
+
+ ast_channel_unref(final_dest_chan);
} else {
ast_debug(1, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name);
ast_hangup(final_dest_chan);
More information about the asterisk-commits
mailing list