[svn-commits] mmichelson: branch mmichelson/queue_bugbug r395073 - /team/mmichelson/queue_b...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jul 22 10:45:37 CDT 2013


Author: mmichelson
Date: Mon Jul 22 10:45:33 2013
New Revision: 395073

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395073
Log:
Resolve a race condition during local channel optimizations.

I need to get the channels that are in the involved bridges of
a local channel optimization. My previous code got a channel from
a channel snapshot and then got that channel's bridge. The problem
is that the channel may already be out of the bridge by the time
we process the local channel optimization. Instead, we just grab
the latest bridge snapshot for the channel snapshot we have. This
is more tolerant of the channel having been removed from the
bridging system. This also makes the code likely to be more efficient
since there is less locking, and we are not having to look into
the internals of an actual bridge, but rather a snapshot.


Modified:
    team/mmichelson/queue_bugbug/apps/app_queue.c

Modified: team/mmichelson/queue_bugbug/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/apps/app_queue.c?view=diff&rev=395073&r1=395072&r2=395073
==============================================================================
--- team/mmichelson/queue_bugbug/apps/app_queue.c (original)
+++ team/mmichelson/queue_bugbug/apps/app_queue.c Mon Jul 22 10:45:33 2013
@@ -5421,12 +5421,12 @@
 
 static int get_ids(void *obj, void *arg, void *data, int flags)
 {
-	struct ast_channel *peer = obj;
+	const char *peer_id = obj;
 	struct ao2_container *id_container = arg;
-	struct ast_channel *exception = data;
-
-	if (peer != exception) {
-		ast_str_container_add(id_container, ast_channel_uniqueid(peer));
+	struct ast_channel_snapshot *exception = data;
+
+	if (strcmp(peer_id, exception->uniqueid)) {
+		ast_str_container_add(id_container, peer_id);
 	}
 
 	return 0;
@@ -5434,32 +5434,17 @@
 
 static int get_channels(struct ao2_container *id_container, struct ast_channel_snapshot *snapshot)
 {
-	RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
-	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
 	RAII_VAR(struct ao2_container *, peers, NULL, ao2_cleanup);
 
-	chan = ast_channel_get_by_name(snapshot->name);
-	if (!chan) {
+	bridge_snapshot = ast_bridge_snapshot_get_latest(snapshot->bridgeid);
+
+	if (!bridge_snapshot) {
+		ast_log(LOG_NOTICE, "Channel %s has no bridge?\n", snapshot->name);
 		return -1;
 	}
 
-	ast_channel_lock(chan);
-	bridge = ast_channel_get_bridge(chan);
-	ast_channel_unlock(chan);
-
-	if (!bridge) {
-		return -1;
-	}
-
-	ast_bridge_lock(bridge);
-	peers = ast_bridge_peers(bridge);
-	ast_bridge_unlock(bridge);
-
-	if (!peers) {
-		return -1;
-	}
-
-	ao2_callback_data(peers, 0, get_ids, id_container, chan);
+	ao2_callback_data(bridge_snapshot->channels, 0, get_ids, id_container, snapshot);
 	return 0;
 }
 




More information about the svn-commits mailing list