[asterisk-commits] rmudgett: branch group/bridge_construction r386410 - in /team/group/bridge_co...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 23 19:10:28 CDT 2013


Author: rmudgett
Date: Tue Apr 23 19:10:24 2013
New Revision: 386410

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386410
Log:
* Make container of ast_bridge_peers() searchable by OBJ_PARTIAL_KEY and not have a lock.

* Add ast_bridge_peers_nolock().

Modified:
    team/group/bridge_construction/include/asterisk/bridging.h
    team/group/bridge_construction/main/bridging.c

Modified: team/group/bridge_construction/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/include/asterisk/bridging.h?view=diff&rev=386410&r1=386409&r2=386410
==============================================================================
--- team/group/bridge_construction/include/asterisk/bridging.h (original)
+++ team/group/bridge_construction/include/asterisk/bridging.h Tue Apr 23 19:10:24 2013
@@ -1318,8 +1318,24 @@
 
 /*!
  * \brief Get a container of all channels in the bridge
+ * \since 12.0.0
+ *
+ * \param bridge The bridge which is already locked.
+ *
+ * \retval NULL Failed to create container
+ * \retval non-NULL Container of channels in the bridge
+ */
+struct ao2_container *ast_bridge_peers_nolock(struct ast_bridge *bridge);
+
+/*!
+ * \brief Get a container of all channels in the bridge
+ * \since 12.0.0
  *
  * \param bridge The bridge
+ *
+ * \note The returned container is a snapshot of channels in the
+ * bridge when called.
+ *
  * \retval NULL Failed to create container
  * \retval non-NULL Container of channels in the bridge
  */

Modified: team/group/bridge_construction/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/main/bridging.c?view=diff&rev=386410&r1=386409&r2=386410
==============================================================================
--- team/group/bridge_construction/main/bridging.c (original)
+++ team/group/bridge_construction/main/bridging.c Tue Apr 23 19:10:24 2013
@@ -4192,34 +4192,72 @@
 static int channel_hash(const void *obj, int flags)
 {
 	const struct ast_channel *chan = obj;
-	const char *chan_name = flags & OBJ_KEY ? obj : ast_channel_name(chan);
-
-	return ast_str_hash(chan_name);
+	const char *name = obj;
+	int hash;
+
+	switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+	default:
+	case OBJ_POINTER:
+		name = ast_channel_name(chan);
+		/* Fall through */
+	case OBJ_KEY:
+		hash = ast_str_hash(name);
+		break;
+	case OBJ_PARTIAL_KEY:
+		/* Should never happen in hash callback. */
+		ast_assert(0);
+		hash = 0;
+		break;
+	}
+	return hash;
 }
 
 static int channel_cmp(void *obj, void *arg, int flags)
 {
-	struct ast_channel *chan1 = obj;
-	struct ast_channel *chan2 = arg;
-	const char *chan2_name = flags & OBJ_KEY ? arg : ast_channel_name(chan2);
-
-	return strcmp(ast_channel_name(chan1), chan2_name) ? 0 : CMP_MATCH;
-}
-
-struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge)
+	const struct ast_channel *left = obj;
+	const struct ast_channel *right = arg;
+	const char *right_name = arg;
+	int cmp;
+
+	switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+	default:
+	case OBJ_POINTER:
+		right_name = ast_channel_name(right);
+		/* Fall through */
+	case OBJ_KEY:
+		cmp = strcmp(ast_channel_name(left), right_name);
+		break;
+	case OBJ_PARTIAL_KEY:
+		cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
+		break;
+	}
+	return cmp ? 0 : CMP_MATCH;
+}
+
+struct ao2_container *ast_bridge_peers_nolock(struct ast_bridge *bridge)
 {
 	struct ao2_container *channels;
 	struct ast_bridge_channel *iter;
 
-	channels = ao2_container_alloc(13, channel_hash, channel_cmp);
+	channels = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK,
+		13, channel_hash, channel_cmp);
 	if (!channels) {
 		return NULL;
 	}
 
-	ast_bridge_lock(bridge);
 	AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
 		ao2_link(channels, iter->chan);
 	}
+
+	return channels;
+}
+
+struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge)
+{
+	struct ao2_container *channels;
+
+	ast_bridge_lock(bridge);
+	channels = ast_bridge_peers_nolock(bridge);
 	ast_bridge_unlock(bridge);
 
 	return channels;




More information about the asterisk-commits mailing list