summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-08-06 16:15:34 +0000
committerJoshua Colp <jcolp@digium.com>2017-08-06 16:15:34 +0000
commit88c65f7cb6f2064ba1b6a7713cb47c9a63790f8f (patch)
tree822227c4e1288aa685bcf996c6dd74303c69d6a9 /bridges
parent2ba29df200f924f34d47371b83d0371c824bc76c (diff)
bridge: Fix stream topology/participant locking and video misrouting.
This change fixes a few locking issues and some video misrouting. 1. When accessing the stream topology of a channel the channel lock must be held to guarantee the topology remains valid. 2. When a channel was joined to a bridge the bridge specific implementation for stream mapping was not invoked, causing video to be misrouted for a brief period of time. ASTERISK-27182 Change-Id: I5d2f779248b84d41c5bb3896bf22ba324b336b03
Diffstat (limited to 'bridges')
-rw-r--r--bridges/bridge_softmix.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c
index c5428a854..b35994895 100644
--- a/bridges/bridge_softmix.c
+++ b/bridges/bridge_softmix.c
@@ -577,13 +577,18 @@ static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast
struct ast_stream_topology *joiner_video = NULL;
struct ast_stream_topology *existing_video = NULL;
struct ast_bridge_channel *participant;
+ int res;
joiner_video = ast_stream_topology_alloc();
if (!joiner_video) {
return;
}
- if (append_source_streams(joiner_video, ast_channel_name(joiner->chan), ast_channel_get_stream_topology(joiner->chan))) {
+ ast_channel_lock(joiner->chan);
+ res = append_source_streams(joiner_video, ast_channel_name(joiner->chan), ast_channel_get_stream_topology(joiner->chan));
+ ast_channel_unlock(joiner->chan);
+
+ if (res) {
goto cleanup;
}
@@ -596,13 +601,18 @@ static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast
if (participant == joiner) {
continue;
}
- if (append_source_streams(existing_video, ast_channel_name(participant->chan),
- ast_channel_get_stream_topology(participant->chan))) {
+ ast_channel_lock(participant->chan);
+ res = append_source_streams(existing_video, ast_channel_name(participant->chan),
+ ast_channel_get_stream_topology(participant->chan));
+ ast_channel_unlock(participant->chan);
+ if (res) {
goto cleanup;
}
}
+ ast_channel_lock(joiner->chan);
joiner_topology = ast_stream_topology_clone(ast_channel_get_stream_topology(joiner->chan));
+ ast_channel_unlock(joiner->chan);
if (!joiner_topology) {
goto cleanup;
}
@@ -617,7 +627,9 @@ static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast
if (participant == joiner) {
continue;
}
+ ast_channel_lock(participant->chan);
participant_topology = ast_stream_topology_clone(ast_channel_get_stream_topology(participant->chan));
+ ast_channel_unlock(participant->chan);
if (!participant_topology) {
goto cleanup;
}
@@ -753,12 +765,16 @@ static int sfu_topologies_on_leave(struct ast_bridge_channel *leaver, struct ast
continue;
}
+ ast_channel_lock(participant->chan);
remove_destination_streams(participant_topology, ast_channel_name(leaver->chan), ast_channel_get_stream_topology(participant->chan));
+ ast_channel_unlock(participant->chan);
ast_channel_request_stream_topology_change(participant->chan, participant_topology, NULL);
ast_stream_topology_free(participant_topology);
}
+ ast_channel_lock(leaver->chan);
remove_destination_streams(leaver_topology, "", ast_channel_get_stream_topology(leaver->chan));
+ ast_channel_unlock(leaver->chan);
ast_channel_request_stream_topology_change(leaver->chan, leaver_topology, NULL);
ast_stream_topology_free(leaver_topology);
@@ -1657,6 +1673,7 @@ static void map_source_to_destinations(const char *source_stream_name, const cha
}
ast_bridge_channel_lock(participant);
+ ast_channel_lock(participant->chan);
topology = ast_channel_get_stream_topology(participant->chan);
for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
@@ -1668,6 +1685,7 @@ static void map_source_to_destinations(const char *source_stream_name, const cha
break;
}
}
+ ast_channel_unlock(participant->chan);
ast_bridge_channel_unlock(participant);
}
}
@@ -1702,16 +1720,9 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st
/* First traversal: re-initialize all of the participants' stream maps */
AST_LIST_TRAVERSE(&bridge->channels, participant, entry) {
- int size;
-
ast_bridge_channel_lock(participant);
- size = ast_stream_topology_get_count(ast_channel_get_stream_topology(participant->chan));
-
- AST_VECTOR_FREE(&participant->stream_map.to_channel);
- AST_VECTOR_FREE(&participant->stream_map.to_bridge);
-
- AST_VECTOR_INIT(&participant->stream_map.to_channel, size);
- AST_VECTOR_INIT(&participant->stream_map.to_bridge, size);
+ AST_VECTOR_RESET(&participant->stream_map.to_channel, AST_VECTOR_ELEM_CLEANUP_NOOP);
+ AST_VECTOR_RESET(&participant->stream_map.to_bridge, AST_VECTOR_ELEM_CLEANUP_NOOP);
ast_bridge_channel_unlock(participant);
}
@@ -1727,6 +1738,8 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st
int i;
struct ast_stream_topology *topology;
+ ast_channel_lock(participant->chan);
+
topology = ast_channel_get_stream_topology(participant->chan);
for (i = 0; i < ast_stream_topology_get_count(topology); ++i) {
@@ -1766,6 +1779,8 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st
}
ast_bridge_channel_unlock(participant);
}
+
+ ast_channel_unlock(participant->chan);
}
}