From 6ae33a4b85b800354ef25c5a23469087066ab2de Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 30 Oct 2020 08:54:17 -0400 Subject: [PATCH] TT#98901 split out ssrc locking Change-Id: I7275a25598be6b9a07364573d687fa478addaa4d --- daemon/codec.c | 53 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index c5c50e238..16806ff3f 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1274,6 +1274,39 @@ static int handler_func_passthrough(struct codec_handler *h, struct media_packet } #ifdef WITH_TRANSCODING +static void __ssrc_lock_both(struct media_packet *mp) { + struct ssrc_ctx *ssrc_in = mp->ssrc_in; + struct ssrc_entry_call *ssrc_in_p = ssrc_in->parent; + struct ssrc_ctx *ssrc_out = mp->ssrc_out; + struct ssrc_entry_call *ssrc_out_p = ssrc_out->parent; + + // we need a nested lock here - both input and output SSRC needs to be locked. + // we don't know the lock order, so try both, and keep trying until we succeed. + while (1) { + mutex_lock(&ssrc_in_p->h.lock); + if (ssrc_in_p == ssrc_out_p) + break; + if (!mutex_trylock(&ssrc_out_p->h.lock)) + break; + mutex_unlock(&ssrc_in_p->h.lock); + + mutex_lock(&ssrc_out_p->h.lock); + if (!mutex_trylock(&ssrc_in_p->h.lock)) + break; + mutex_unlock(&ssrc_out_p->h.lock); + } +} +static void __ssrc_unlock_both(struct media_packet *mp) { + struct ssrc_ctx *ssrc_in = mp->ssrc_in; + struct ssrc_entry_call *ssrc_in_p = ssrc_in->parent; + struct ssrc_ctx *ssrc_out = mp->ssrc_out; + struct ssrc_entry_call *ssrc_out_p = ssrc_out->parent; + + mutex_unlock(&ssrc_in_p->h.lock); + if (ssrc_in_p != ssrc_out_p) + mutex_unlock(&ssrc_out_p->h.lock); +} + static int __handler_func_sequencer(struct media_packet *mp, struct transcode_packet *packet) { struct codec_handler *h = packet->handler; @@ -1307,21 +1340,7 @@ static int __handler_func_sequencer(struct media_packet *mp, struct transcode_pa if (packet->ignore_seq) seq_next_packet = packet_sequencer_force_next_packet; - // we need a nested lock here - both input and output SSRC needs to be locked. - // we don't know the lock order, so try both, and keep trying until we succeed. - while (1) { - mutex_lock(&ssrc_in_p->h.lock); - if (ssrc_in_p == ssrc_out_p) - break; - if (!mutex_trylock(&ssrc_out_p->h.lock)) - break; - mutex_unlock(&ssrc_in_p->h.lock); - - mutex_lock(&ssrc_out_p->h.lock); - if (!mutex_trylock(&ssrc_in_p->h.lock)) - break; - mutex_unlock(&ssrc_out_p->h.lock); - } + __ssrc_lock_both(mp); packet_sequencer_init(&ssrc_in_p->sequencer, (GDestroyNotify) __transcode_packet_free); @@ -1377,9 +1396,7 @@ next: } out: - mutex_unlock(&ssrc_in_p->h.lock); - if (ssrc_in_p != ssrc_out_p) - mutex_unlock(&ssrc_out_p->h.lock); + __ssrc_unlock_both(mp); obj_put(&ch->h); return 0;