Skip to content

Commit

Permalink
Fix rare race condition in VideoRoom (see meetecho#3242) (meetecho#3247)
Browse files Browse the repository at this point in the history
  • Loading branch information
lminiero authored and Alexander Malaev committed Nov 20, 2023
1 parent 8592559 commit ba3ab0c
Showing 1 changed file with 43 additions and 6 deletions.
49 changes: 43 additions & 6 deletions src/plugins/janus_videoroom.c
Original file line number Diff line number Diff line change
Expand Up @@ -2239,6 +2239,13 @@ typedef struct janus_videoroom_subscriber_stream {
janus_refcount ref;
} janus_videoroom_subscriber_stream;

typedef struct janus_videoroom_stream_mapping {
janus_videoroom_publisher_stream *ps;
janus_videoroom_subscriber *subscriber;
janus_videoroom_subscriber_stream *ss;
gboolean unref_ss;
} janus_videoroom_stream_mapping;

typedef struct janus_videoroom_rtp_relay_packet {
janus_videoroom_publisher_stream *source;
janus_rtp_header *data;
Expand Down Expand Up @@ -8469,7 +8476,7 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
participant->e2ee = FALSE;
/* Get rid of streams */
janus_mutex_lock(&participant->streams_mutex);
GList *subscribers = NULL;
GList *subscribers = NULL, *mappings = NULL;
GList *temp = participant->streams;
while(temp) {
janus_videoroom_publisher_stream *ps = (janus_videoroom_publisher_stream *)temp->data;
Expand All @@ -8486,8 +8493,16 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
janus_refcount_increase(&ss->subscriber->session->ref);
subscribers = g_list_append(subscribers, ss->subscriber);
}
/* Remove the subscription (turns the m-line to inactive) */
janus_videoroom_subscriber_stream_remove(ss, ps, FALSE);
/* Take note of the subscription to remove */
janus_videoroom_stream_mapping *m = g_malloc(sizeof(janus_videoroom_stream_mapping));
janus_refcount_increase(&ps->ref);
janus_refcount_increase(&ss->ref);
janus_refcount_increase(&ss->subscriber->ref);
m->ps = ps;
m->ss = ss;
m->unref_ss = (g_slist_find(ps->subscribers, ss) != NULL);
m->subscriber = ss->subscriber;
mappings = g_list_append(mappings, m);
}
}
g_slist_free(ps->subscribers);
Expand All @@ -8498,6 +8513,28 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
janus_mutex_unlock(&ps->subscribers_mutex);
temp = temp->next;
}
if(mappings) {
temp = mappings;
while(temp) {
janus_videoroom_stream_mapping *m = (janus_videoroom_stream_mapping *)temp->data;
/* Remove the subscription (turns the m-line to inactive) */
janus_videoroom_publisher_stream *ps = m->ps;
janus_videoroom_subscriber *subscriber = m->subscriber;
janus_videoroom_subscriber_stream *ss = m->ss;
if(subscriber) {
janus_mutex_lock(&subscriber->streams_mutex);
janus_videoroom_subscriber_stream_remove(ss, ps, TRUE);
janus_mutex_unlock(&subscriber->streams_mutex);
if(m->unref_ss)
janus_refcount_decrease(&ss->ref);
janus_refcount_decrease(&subscriber->ref);
}
janus_refcount_decrease(&ss->ref);
janus_refcount_decrease(&ps->ref);
temp = temp->next;
}
g_list_free_full(mappings, (GDestroyNotify)g_free);
}
/* Any subscriber session to update? */
janus_videoroom *room = participant->room;
if(subscribers != NULL) {
Expand Down Expand Up @@ -8595,8 +8632,8 @@ static void janus_videoroom_hangup_media_internal(gpointer session_data) {
}
list = list->next;
}
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
temp = temp->next;
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
}
/* Free streams */
g_list_free(subscriber->streams);
Expand Down Expand Up @@ -9649,8 +9686,8 @@ static void *janus_videoroom_handler(void *data) {
GList *temp = subscriber->streams;
while(temp) {
janus_videoroom_subscriber_stream *s = (janus_videoroom_subscriber_stream *)temp->data;
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
temp = temp->next;
janus_videoroom_subscriber_stream_remove(s, NULL, TRUE);
}
g_list_free(subscriber->streams);
subscriber->streams = NULL;
Expand Down Expand Up @@ -10432,10 +10469,10 @@ static void *janus_videoroom_handler(void *data) {
list = list->next;
continue;
}
janus_videoroom_subscriber_stream_remove(stream, ps, TRUE);
if(stream->type != JANUS_VIDEOROOM_MEDIA_DATA)
changes++;
list = list->next;
janus_videoroom_subscriber_stream_remove(stream, ps, TRUE);
}
temp = temp->next;
}
Expand Down

0 comments on commit ba3ab0c

Please sign in to comment.