[asterisk-commits] russell: branch russell/chan_refcount r82302 - /team/russell/chan_refcount/main/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Sep 12 17:51:31 CDT 2007
Author: russell
Date: Wed Sep 12 17:51:30 2007
New Revision: 82302
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82302
Log:
add the channel iterator and channel get funcs
Modified:
team/russell/chan_refcount/main/channel.c
Modified: team/russell/chan_refcount/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/main/channel.c?view=diff&rev=82302&r1=82301&r2=82302
==============================================================================
--- team/russell/chan_refcount/main/channel.c (original)
+++ team/russell/chan_refcount/main/channel.c Wed Sep 12 17:51:30 2007
@@ -1001,6 +1001,7 @@
ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
}
+#if 0
/*!
* \brief Helper function to find channels.
*
@@ -1142,6 +1143,136 @@
{
return channel_find_locked(chan, NULL, 0, context, exten);
}
+#endif
+
+struct ast_channel_iterator {
+ struct ao2_iterator _i;
+ const char *_name;
+ size_t _name_len;
+ const char *_exten;
+ const char *_context;
+};
+
+struct ast_channel_iterator *ast_channel_iterator_destroy(struct ast_channel_iterator *i)
+{
+ if (i->_name)
+ ast_free((void *) i->_name);
+ if (i->_exten)
+ ast_free((void *) i->_exten);
+ if (i->_context)
+ ast_free((void *) i->_context);
+ ast_free(i);
+
+ return NULL;
+}
+
+static struct ast_channel_iterator *ast_channel_iterator_new(const char *name,
+ size_t name_len, const char *exten, const char *context)
+{
+ struct ast_channel_iterator *i;
+
+ if (!(i = ast_calloc(1, sizeof(*i))))
+ return NULL;
+
+ if (!ast_strlen_zero(exten) && !(i->_exten = ast_strdup(exten)))
+ goto return_error;
+
+ if (!ast_strlen_zero(context) && !(i->_context = ast_strdup(context)))
+ goto return_error;
+
+ if (!ast_strlen_zero(name) && !(i->_name = ast_strdup(name)))
+ goto return_error;
+
+ i->_name_len = name_len;
+
+ i->_i = ao2_iterator_init(channels, 0);
+
+ return i;
+
+return_error:
+ if (i->_exten)
+ ast_free((void *) i->_exten);
+ if (i->_context)
+ ast_free((void *) i->_context);
+ ast_free(i);
+
+ return NULL;
+}
+
+struct ast_channel_iterator *ast_channel_iterator_by_exten_new(const char *exten,
+ const char *context)
+{
+ return ast_channel_iterator_new(NULL, 0, exten, context);
+}
+
+struct ast_channel_iterator *ast_channel_iterator_by_name_new(const char *name,
+ size_t name_len)
+{
+ return ast_channel_iterator_new(name, name_len, NULL, NULL);
+}
+
+struct ast_channel_iterator *ast_channel_iterator_all_new(void)
+{
+ return ast_channel_iterator_new(NULL, 0, NULL, NULL);
+}
+
+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)) {
+ if (i->_name) { /* match by name */
+ if ((!i->_name_len && strcasecmp(chan->name, i->_name)) ||
+ (i->_name_len && strncasecmp(chan->name, 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))
+ continue; /* context match failed */
+ if (strcasecmp(chan->exten, i->_exten) &&
+ strcasecmp(chan->macroexten, i->_exten))
+ continue; /* exten match failed */
+ }
+ break; /* chan points to the next chan desired. */
+ }
+
+ return chan;
+}
+
+static struct ast_channel *ast_channel_get_full(const char *name, size_t name_len,
+ const char *exten, const char *context)
+{
+ struct ast_channel tmp_chan = {
+ .name = name,
+ /* This is sort of a hack. Basically, we're using an arbitrary field
+ * in ast_channel to pass the name_len for a prefix match. If this
+ * gets changed, then the compare callback must be changed, too. */
+ .rings = name_len,
+ };
+
+ if (exten)
+ ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
+
+ if (context)
+ ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
+
+ return ao2_find(channels, &tmp_chan, OBJ_POINTER);
+}
+
+struct ast_channel *ast_channel_get_by_name(const char *name)
+{
+ return ast_channel_get_full(name, 0, NULL, NULL);
+}
+
+struct ast_channel *ast_channel_get_by_name_prefix(const char *name, size_t name_len)
+{
+ return ast_channel_get_full(name, name_len, NULL, NULL);
+}
+
+struct ast_channel *ast_channel_get_by_exten(const char *exten, const char *context)
+{
+ return ast_channel_get_full(NULL, 0, exten, context);
+}
/*! \brief Wait, look for hangups and condition arg */
int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data)
@@ -1478,7 +1609,7 @@
chan->hangupcause,
ast_cause2str(chan->hangupcause)
);
- ast_channel_free(chan);
+ chan = ast_channel_free(chan);
if (cdr)
ast_cdr_detach(cdr);
@@ -3704,7 +3835,7 @@
clone->hangupcause,
ast_cause2str(clone->hangupcause)
);
- ast_channel_free(clone);
+ clone = ast_channel_free(clone);
} else {
ast_debug(1, "Released clone lock on '%s'\n", clone->name);
ast_set_flag(clone, AST_FLAG_ZOMBIE);
More information about the asterisk-commits
mailing list