Skip to content

Commit cec0afa

Browse files
committed
MT#55283 clean up RTCP send locking
Fixes regression from Ib4285e7aae RTCP multiplexing requires the RTCP sender to maybe lock the same output stream, maybe lock some other one. Allow for both. Change-Id: I6fcef32e656f8f0de46ad777f11a19c259ce35c7
1 parent e03f814 commit cec0afa

File tree

4 files changed

+22
-12
lines changed

4 files changed

+22
-12
lines changed

daemon/codec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,7 @@ static void __rtcp_timer_run(struct codec_timer *ct) {
13711371

13721372
for (GList *l = ssrc_out.head; l; l = l->next) {
13731373
struct ssrc_entry_call *se = l->data;
1374-
rtcp_send_report(media, se);
1374+
rtcp_send_report(media, se, NULL);
13751375
}
13761376

13771377
rwlock_unlock_r(&rt->call->master_lock);

daemon/media_player.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,13 @@ struct send_timer *send_timer_new(struct packet_stream *ps) {
306306

307307
// call is locked in R
308308
// ssrc_out is locked
309+
// st->sink is locked
309310
static void send_timer_rtcp(struct send_timer *st, struct ssrc_entry_call *ssrc_out) {
310311
struct call_media *media = st->sink ? st->sink->media : NULL;
311312
if (!media)
312313
return;
313314

314-
rtcp_send_report(media, ssrc_out);
315+
rtcp_send_report(media, ssrc_out, st->sink);
315316

316317
ssrc_out->next_rtcp = rtpe_now;
317318
ssrc_out->next_rtcp += 5000000 + (ssl_random() % 2000000);
@@ -408,6 +409,7 @@ static void __send_timer_send_common(struct send_timer *st, struct codec_packet
408409
log_info_pop();
409410
}
410411

412+
// sink->lock is held
411413
static void __send_timer_rtcp(struct send_timer *st, struct ssrc_entry_call *ssrc_out) {
412414
// do we send RTCP?
413415
if (!ssrc_out)
@@ -436,9 +438,10 @@ static void send_timer_send_lock(struct send_timer *st, struct codec_packet *cp)
436438

437439
__send_timer_send_common(st, cp);
438440

441+
__send_timer_rtcp(st, ssrc_out);
442+
439443
mutex_unlock(&st->sink->lock);
440444

441-
__send_timer_rtcp(st, ssrc_out);
442445
ssrc_entry_release(ssrc_out);
443446

444447
rwlock_unlock_r(&call->master_lock);

daemon/rtcp.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,8 +1550,10 @@ static void rtcp_receiver_reports(ssrc_q *out, struct ssrc_hash *hash) {
15501550

15511551

15521552
// call must be locked in R
1553-
// no in_lock or out_lock must be held
1554-
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out) {
1553+
// if a `ps` is locked, it must be passed as argument
1554+
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out,
1555+
const struct packet_stream *locked)
1556+
{
15551557
// figure out where to send it
15561558
struct packet_stream *ps = media->streams.head->data;
15571559
// crypto context is held separately
@@ -1562,16 +1564,15 @@ void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out
15621564
else {
15631565
if (PS_ISSET(rtcp_ps, RTCP))
15641566
ps = rtcp_ps;
1565-
else
1566-
rtcp_ps = ps;
15671567
}
15681568

1569-
LOCK(&ps->lock);
1569+
if (ps != locked)
1570+
mutex_lock(&ps->lock);
15701571

1571-
if (!ps->selected_sfd || !rtcp_ps->selected_sfd)
1572-
return;
1572+
if (!ps->selected_sfd)
1573+
goto out;
15731574
if (ps->selected_sfd->socket.fd == -1 || ps->endpoint.address.family == NULL)
1574-
return;
1575+
goto out;
15751576

15761577
log_info_stream_fd(ps->selected_sfd);
15771578

@@ -1623,6 +1624,11 @@ void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out
16231624
struct ssrc_receiver_report *srr = t_queue_pop_head(&srrs);
16241625
g_free(srr);
16251626
}
1627+
1628+
out:
1629+
if (ps != locked)
1630+
mutex_unlock(&ps->lock);
1631+
16261632
}
16271633

16281634

include/rtcp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ rtcp_filter_func rtcp_avpf2avp_filter;
3030
void rtcp_init(void);
3131

3232

33-
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out);
33+
void rtcp_send_report(struct call_media *media, struct ssrc_entry_call *ssrc_out,
34+
const struct packet_stream *locked);
3435

3536
#endif

0 commit comments

Comments
 (0)