From 9ca662f06e8710df8b053c31fdc7028b812c5d3d Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 2 Jun 2021 16:43:43 -0700 Subject: [PATCH] fix deadlocks in track subscription --- pkg/rtc/mediatrack.go | 7 +++++-- pkg/rtc/room.go | 9 +++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/rtc/mediatrack.go b/pkg/rtc/mediatrack.go index 8c6174426..140b046ac 100644 --- a/pkg/rtc/mediatrack.go +++ b/pkg/rtc/mediatrack.go @@ -212,8 +212,11 @@ func (t *MediaTrack) AddSubscriber(sub types.Participant) error { t.subscribedTracks[sub.ID()] = subTrack t.receiver.AddDownTrack(downTrack, true) - sub.AddSubscribedTrack(t.params.ParticipantID, subTrack) - sub.Negotiate() + // since sub will lock, run it in a gorountine to avoid deadlocks + go func() { + sub.AddSubscribedTrack(t.params.ParticipantID, subTrack) + sub.Negotiate() + }() t.params.Stats.AddSubscribedTrack(t.kind.String()) return nil diff --git a/pkg/rtc/room.go b/pkg/rtc/room.go index 19294bc2f..dbb29540d 100644 --- a/pkg/rtc/room.go +++ b/pkg/rtc/room.go @@ -318,14 +318,12 @@ func (r *Room) OnParticipantChanged(f func(participant types.Participant)) { r.onParticipantChanged = f } +// checks if participant should be autosubscribed to new tracks, assumes lock is already acquired func (r *Room) autoSubscribe(participant types.Participant) bool { if !participant.CanSubscribe() { return false } - r.lock.RLock() - defer r.lock.RUnlock() - opts := r.participantOpts[participant.Identity()] // default to true if no options are set if opts != nil && !opts.AutoSubscribe { @@ -402,7 +400,10 @@ func (r *Room) onDataPacket(source types.Participant, dp *livekit.DataPacket) { } func (r *Room) subscribeToExistingTracks(p types.Participant) { - if !r.autoSubscribe(p) { + r.lock.RLock() + shouldSubscribe := r.autoSubscribe(p) + r.lock.RUnlock() + if !shouldSubscribe { return }