[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