[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