Skip to content

Commit ba3ab0c

Browse files
lminieroAlexander Malaev
authored and
Alexander Malaev
committed
Fix rare race condition in VideoRoom (see meetecho#3242) (meetecho#3247)
1 parent 8592559 commit ba3ab0c

File tree

1 file changed

+43
-6
lines changed

1 file changed

+43
-6
lines changed

src/plugins/janus_videoroom.c

+43-6
Original file line numberDiff line numberDiff line change
@@ -2239,6 +2239,13 @@ typedef struct janus_videoroom_subscriber_stream {
22392239
janus_refcount ref;
22402240
} janus_videoroom_subscriber_stream;
22412241

2242+
typedef struct janus_videoroom_stream_mapping {
2243+
janus_videoroom_publisher_stream *ps;
2244+
janus_videoroom_subscriber *subscriber;
2245+
janus_videoroom_subscriber_stream *ss;
2246+
gboolean unref_ss;
2247+
} janus_videoroom_stream_mapping;
2248+
22422249
typedef struct janus_videoroom_rtp_relay_packet {
22432250
janus_videoroom_publisher_stream *source;
22442251
janus_rtp_header *data;
@@ -8469,7 +8476,7 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
84698476
participant->e2ee = FALSE;
84708477
/* Get rid of streams */
84718478
janus_mutex_lock(&participant->streams_mutex);
8472-
GList *subscribers = NULL;
8479+
GList *subscribers = NULL, *mappings = NULL;
84738480
GList *temp = participant->streams;
84748481
while(temp) {
84758482
janus_videoroom_publisher_stream *ps = (janus_videoroom_publisher_stream *)temp->data;
@@ -8486,8 +8493,16 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
84868493
janus_refcount_increase(&ss->subscriber->session->ref);
84878494
subscribers = g_list_append(subscribers, ss->subscriber);
84888495
}
8489-
/* Remove the subscription (turns the m-line to inactive) */
8490-
janus_videoroom_subscriber_stream_remove(ss, ps, FALSE);
8496+
/* Take note of the subscription to remove */
8497+
janus_videoroom_stream_mapping *m = g_malloc(sizeof(janus_videoroom_stream_mapping));
8498+
janus_refcount_increase(&ps->ref);
8499+
janus_refcount_increase(&ss->ref);
8500+
janus_refcount_increase(&ss->subscriber->ref);
8501+
m->ps = ps;
8502+
m->ss = ss;
8503+
m->unref_ss = (g_slist_find(ps->subscribers, ss) != NULL);
8504+
m->subscriber = ss->subscriber;
8505+
mappings = g_list_append(mappings, m);
84918506
}
84928507
}
84938508
g_slist_free(ps->subscribers);
@@ -8498,6 +8513,28 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
84988513
janus_mutex_unlock(&ps->subscribers_mutex);
84998514
temp = temp->next;
85008515
}
8516+
if(mappings) {
8517+
temp = mappings;
8518+
while(temp) {
8519+
janus_videoroom_stream_mapping *m = (janus_videoroom_stream_mapping *)temp->data;
8520+
/* Remove the subscription (turns the m-line to inactive) */
8521+
janus_videoroom_publisher_stream *ps = m->ps;
8522+
janus_videoroom_subscriber *subscriber = m->subscriber;
8523+
janus_videoroom_subscriber_stream *ss = m->ss;
8524+
if(subscriber) {
8525+
janus_mutex_lock(&subscriber->streams_mutex);
8526+
janus_videoroom_subscriber_stream_remove(ss, ps, TRUE);
8527+
janus_mutex_unlock(&subscriber->streams_mutex);
8528+
if(m->unref_ss)
8529+
janus_refcount_decrease(&ss->ref);
8530+
janus_refcount_decrease(&subscriber->ref);
8531+
}
8532+
janus_refcount_decrease(&ss->ref);
8533+
janus_refcount_decrease(&ps->ref);
8534+
temp = temp->next;
8535+
}
8536+
g_list_free_full(mappings, (GDestroyNotify)g_free);
8537+
}
85018538
/* Any subscriber session to update? */
85028539
janus_videoroom *room = participant->room;
85038540
if(subscribers != NULL) {
@@ -8595,8 +8632,8 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
85958632
}
85968633
list = list->next;
85978634
}
8598-
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
85998635
temp = temp->next;
8636+
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
86008637
}
86018638
/* Free streams */
86028639
g_list_free(subscriber->streams);
@@ -9649,8 +9686,8 @@ static void *janus_videoroom_handler(void *data) {
96499686
GList *temp = subscriber->streams;
96509687
while(temp) {
96519688
janus_videoroom_subscriber_stream *s = (janus_videoroom_subscriber_stream *)temp->data;
9652-
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
96539689
temp = temp->next;
9690+
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
96549691
}
96559692
g_list_free(subscriber->streams);
96569693
subscriber->streams = NULL;
@@ -10432,10 +10469,10 @@ static void *janus_videoroom_handler(void *data) {
1043210469
list = list->next;
1043310470
continue;
1043410471
}
10435-
janus_videoroom_subscriber_stream_remove(stream, ps, TRUE);
1043610472
if(stream->type != JANUS_VIDEOROOM_MEDIA_DATA)
1043710473
changes++;
1043810474
list = list->next;
10475+
janus_videoroom_subscriber_stream_remove(stream, ps, TRUE);
1043910476
}
1044010477
temp = temp->next;
1044110478
}

0 commit comments

Comments
 (0)