[asterisk-commits] russell: branch russell/ast_channel_ao2 r174215 - in /team/russell/ast_channe...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Feb 8 07:01:21 CST 2009
Author: russell
Date: Sun Feb 8 07:01:20 2009
New Revision: 174215
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=174215
Log:
formatting, and docs for ast_bridged_channel() and ast_channel_iterator_next()
Modified:
team/russell/ast_channel_ao2/include/asterisk/channel.h
team/russell/ast_channel_ao2/main/channel.c
Modified: team/russell/ast_channel_ao2/include/asterisk/channel.h
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/include/asterisk/channel.h?view=diff&rev=174215&r1=174214&r2=174215
==============================================================================
--- team/russell/ast_channel_ao2/include/asterisk/channel.h (original)
+++ team/russell/ast_channel_ao2/include/asterisk/channel.h Sun Feb 8 07:01:20 2009
@@ -1495,8 +1495,23 @@
*/
int ast_do_masquerade(struct ast_channel *chan);
-/*! \brief Find bridged channel
- \param chan Current channel
+/*!
+ * \brief Find bridged channel
+ *
+ * \note This function does _not_ return a reference to the bridged channel.
+ * The reason for this is mostly historical. It _should_ return a reference,
+ * but it will take a lot of work to make the code base account for that.
+ * So, for the now, the old rules still apply for how to handle this function.
+ * If this function is being used from the channel thread that owns the channel,
+ * then a reference is already held, and channel locking is not required to
+ * guarantee that the channel will stay around. If this function is used
+ * outside of the associated channel thread, the channel parameter 'chan'
+ * MUST be locked before calling this function. Also, 'chan' must reamain locked
+ * for the entire time that the result of this function is being used.
+ *
+ * \param chan Current channel
+ *
+ * \return A pointer to the bridged channel
*/
struct ast_channel *ast_bridged_channel(struct ast_channel *chan);
Modified: team/russell/ast_channel_ao2/main/channel.c
URL: http://svn.digium.com/svn-view/asterisk/team/russell/ast_channel_ao2/main/channel.c?view=diff&rev=174215&r1=174214&r2=174215
==============================================================================
--- team/russell/ast_channel_ao2/main/channel.c (original)
+++ team/russell/ast_channel_ao2/main/channel.c Sun Feb 8 07:01:20 2009
@@ -1126,12 +1126,21 @@
struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_iterator *i)
{
- if (i->name)
+ if (i->name) {
ast_free((void *) i->name);
- if (i->exten)
+ i->name = NULL;
+ }
+
+ if (i->exten) {
ast_free((void *) i->exten);
- if (i->context)
+ i->exten = NULL;
+ }
+
+ if (i->context) {
ast_free((void *) i->context);
+ i->context = NULL;
+ }
+
ast_free(i);
return NULL;
@@ -1142,17 +1151,21 @@
{
struct ast_channel_iterator *i;
- if (!(i = ast_calloc(1, sizeof(*i))))
+ if (!(i = ast_calloc(1, sizeof(*i)))) {
return NULL;
-
- if (!ast_strlen_zero(exten) && !(i->exten = ast_strdup(exten)))
+ }
+
+ if (!ast_strlen_zero(exten) && !(i->exten = ast_strdup(exten))) {
goto return_error;
-
- if (!ast_strlen_zero(context) && !(i->context = ast_strdup(context)))
+ }
+
+ if (!ast_strlen_zero(context) && !(i->context = ast_strdup(context))) {
goto return_error;
-
- if (!ast_strlen_zero(name) && !(i->name = ast_strdup(name)))
+ }
+
+ if (!ast_strlen_zero(name) && !(i->name = ast_strdup(name))) {
goto return_error;
+ }
i->name_len = name_len;
@@ -1161,10 +1174,16 @@
return i;
return_error:
- if (i->exten)
+ if (i->exten) {
ast_free((void *) i->exten);
- if (i->context)
+ i->exten = NULL;
+ }
+
+ if (i->context) {
ast_free((void *) i->context);
+ i->context = NULL;
+ }
+
ast_free(i);
return NULL;
@@ -1187,29 +1206,47 @@
return ast_channel_iterator_new(ao2_flags, NULL, 0, NULL, NULL);
}
+/*!
+ * \note This function will be reduced to 1 line of code once ao2 supports
+ * returning multiple objects from an ao2_callback() using OBJ_MULTIPLE.
+ */
struct ast_channel *ast_channel_iterator_next(struct ast_channel_iterator *i)
{
struct ast_channel *chan = NULL;
- for (; (chan = ao2_iterator_next(&i->i)); ast_channel_unref(chan)) {
+ for (; (chan = ao2_iterator_next(&i->i));
+ ast_channel_unlock(chan), ast_channel_unref(chan)) {
+
+ ast_channel_lock(chan);
+
if (i->name) { /* match by name */
if (!i->name_len) {
- if (strcasecmp(chan->name, i->name) && strcasecmp(chan->uniqueid, i->name))
+ if (strcasecmp(chan->name, i->name) && strcasecmp(chan->uniqueid, i->name)) {
continue; /* name match failed */
+ }
} else {
if (strncasecmp(chan->name, i->name, i->name_len) &&
- strncasecmp(chan->uniqueid, i->name, i->name_len))
+ strncasecmp(chan->uniqueid, i->name, i->name_len)) {
continue; /* name match failed */
+ }
}
} else if (i->exten) {
if (i->context && strcasecmp(chan->context, i->context) &&
- strcasecmp(chan->macrocontext, i->context))
+ strcasecmp(chan->macrocontext, i->context)) {
continue; /* context match failed */
+ }
+
if (strcasecmp(chan->exten, i->exten) &&
- strcasecmp(chan->macroexten, i->exten))
+ strcasecmp(chan->macroexten, i->exten)) {
continue; /* exten match failed */
- }
+ }
+ }
+
break; /* chan points to the next chan desired. */
+ }
+
+ if (chan) {
+ ast_channel_unlock(chan);
}
return chan;
@@ -1226,11 +1263,13 @@
.rings = name_len,
};
- if (exten)
+ if (exten) {
ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
-
- if (context)
+ }
+
+ if (context) {
ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
+ }
return ao2_find(channels, &tmp_chan, OBJ_POINTER);
}
@@ -5032,29 +5071,33 @@
* gets changed, then the uses of ao2_find() must be changed, too. */
name_len = cmp_args->rings;
+ ast_channel_lock(chan);
+
if (cmp_args->name) { /* match by name */
if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
- (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
+ (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
ret = 0; /* name match failed */
}
} else if (cmp_args->exten) {
if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
- strcasecmp(chan->macrocontext, cmp_args->context)) {
+ strcasecmp(chan->macrocontext, cmp_args->context)) {
ret = 0; /* context match failed */
}
if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
- strcasecmp(chan->macroexten, cmp_args->exten)) {
+ strcasecmp(chan->macroexten, cmp_args->exten)) {
ret = 0; /* exten match failed */
}
}
+ ast_channel_unlock(chan);
+
return ret;
}
void ast_channels_init(void)
{
channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS,
- ast_channel_hash_cb, ast_channel_cmp_cb);
+ ast_channel_hash_cb, ast_channel_cmp_cb);
ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
}
More information about the asterisk-commits
mailing list