From 14b694bf25732f0e90b968cb65a735b85c8c466c Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 3 Mar 2025 10:41:48 -0400 Subject: [PATCH] MT#61625 make recursive update_init_subs Instead of explicitly triggering an update of subscribers for A and B during an offer/answer, trigger it only for one side (A) and then iterate through all subscribers and subsriptions and update them all. This automatically triggers an update for B, as well as any other existing subscriptions that might be affected. Use a monotonically increading update iterator counter to track which medias have been updated so we don't run into infinite recursion. Change-Id: Ie2fba8ff9c5a011bbe932559ac06e1634029a091 --- daemon/call.c | 49 ++++++++++++++++++++++++++++++++++++------------- include/call.h | 2 ++ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 14c6b53eb..dd5385ec1 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2621,8 +2621,12 @@ void codecs_offer_answer(struct call_media *media, struct call_media *other_medi /* called with call->master_lock held in W */ __attribute__((nonnull(1))) static void __update_init_subscribers(struct call_media *media, struct stream_params *sp, - sdp_ng_flags *flags, enum ng_opmode opmode) + sdp_ng_flags *flags, enum ng_opmode opmode, unsigned int iter) { + if (media->update_iter == iter) + return; + media->update_iter = iter; + recording_setup_media(media); /* should be set on media directly? Currently absent */ @@ -2643,6 +2647,13 @@ static void __update_init_subscribers(struct call_media *media, struct stream_pa struct call_media * sub_media = ms->media; if (!__streams_set_sinks(media, sub_media, flags, &ms->attrs)) ilog(LOG_WARN, "Error initialising streams"); + __update_init_subscribers(sub_media, NULL, NULL, opmode, iter); + } + for (__auto_type l = media->media_subscriptions.head; l; l = l->next) + { + struct media_subscription * ms = l->data; + struct call_media *sub_media = ms->media; + __update_init_subscribers(sub_media, NULL, NULL, opmode, iter); } /* we are now ready to fire up ICE if so desired and requested */ @@ -2663,21 +2674,36 @@ static void __update_init_subscribers(struct call_media *media, struct stream_pa mqtt_timer_start(&media->mqtt_timer, media->call, media); } +__attribute__((nonnull(1))) +static void update_init_subscribers(struct call_media *media, struct stream_params *sp, + sdp_ng_flags *flags, enum ng_opmode opmode) +{ + g_autoptr(GHashTable) recurs_ht = g_hash_table_new(g_direct_hash, g_direct_equal); + __update_init_subscribers(media, sp, flags, opmode, ++media->call->update_iter); +} + /* called with call->master_lock held in W */ void update_init_monologue_subscribers(struct call_monologue *ml, enum ng_opmode opmode) { + unsigned int update_iter = ++ml->call->update_iter; + for (unsigned int i = 0; i < ml->medias->len; i++) { struct call_media *media = ml->medias->pdata[i]; if (!media) continue; - __update_init_subscribers(media, NULL, NULL, opmode); + __update_init_subscribers(media, NULL, NULL, opmode, update_iter); } } /* called with call->master_lock held in W */ static void __update_init_medias(const medias_q *medias, enum ng_opmode opmode) { + if (!medias->length) + return; + + unsigned int update_iter = ++medias->head->data->call->update_iter; + for (auto_iter(l, medias->head); l; l = l->next) - __update_init_subscribers(l->data, NULL, NULL, opmode); + __update_init_subscribers(l->data, NULL, NULL, opmode, update_iter); } /* called with call->master_lock held in W */ @@ -3238,8 +3264,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q * goto error_ports; } - __update_init_subscribers(sender_media, sp, flags, flags->opmode); - __update_init_subscribers(receiver_media, NULL, NULL, flags->opmode); + update_init_subscribers(sender_media, sp, flags, flags->opmode); __update_init_medias(&old_medias, flags->opmode); media_update_transcoding_flag(receiver_media); @@ -3657,8 +3682,7 @@ static int monologue_subscribe_request1(struct call_monologue *src_ml, struct ca if (!__init_streams(dst_media, NULL, flags)) return -1; - __update_init_subscribers(src_media, NULL, NULL, flags->opmode); - __update_init_subscribers(dst_media, NULL, NULL, flags->opmode); + update_init_subscribers(src_media, NULL, NULL, flags->opmode); } return 0; @@ -3750,7 +3774,7 @@ int monologue_subscribe_answer(struct call_monologue *dst_ml, sdp_ng_flags *flag /* TODO: check answer SDP parameters */ MEDIA_SET(dst_media, INITIALIZED); - __update_init_subscribers(dst_media, sp, flags, flags->opmode); + update_init_subscribers(dst_media, sp, flags, flags->opmode); __media_unconfirm(dst_media, "subscribe answer event"); } @@ -3768,7 +3792,7 @@ int monologue_subscribe_answer(struct call_monologue *dst_ml, sdp_ng_flags *flag struct media_subscription * ms = sub->data; if (!g_queue_find(&mls, ms->monologue)) { media_update_transcoding_flag(ms->media); - __update_init_subscribers(ms->media, NULL, NULL, flags->opmode); + update_init_subscribers(ms->media, NULL, NULL, flags->opmode); __media_unconfirm(ms->media, "subscribe answer event"); g_queue_push_tail(&mls, ms->monologue); } @@ -3798,12 +3822,12 @@ int monologue_unsubscribe(struct call_monologue *dst_ml, sdp_ng_flags *flags) { __media_unconfirm(src_media, "media unsubscribe"); __unsubscribe_media_link(media, l); - __update_init_subscribers(src_media, NULL, NULL, flags->opmode); + update_init_subscribers(src_media, NULL, NULL, flags->opmode); l = next; } - __update_init_subscribers(media, NULL, NULL, flags->opmode); + update_init_subscribers(media, NULL, NULL, flags->opmode); } return 0; @@ -3863,8 +3887,7 @@ void dialogue_connect(struct call_monologue *src_ml, struct call_monologue *dst_ codec_handlers_update(dst_media, src_media, .allow_asymmetric = !!flags->allow_asymmetric_codecs); - __update_init_subscribers(src_media, NULL, NULL, flags->opmode); - __update_init_subscribers(dst_media, NULL, NULL, flags->opmode); + update_init_subscribers(src_media, NULL, NULL, flags->opmode); __update_init_medias(&medias, flags->opmode); } } diff --git a/include/call.h b/include/call.h index 14b71eb4c..8b7f6efe3 100644 --- a/include/call.h +++ b/include/call.h @@ -557,6 +557,7 @@ struct call_media { int maxptime; /* from SDP */ atomic64 media_flags; + unsigned int update_iter; }; TYPED_GPTRARRAY(medias_arr, struct call_media) @@ -798,6 +799,7 @@ struct call { enum block_dtmf_mode block_dtmf; atomic64 call_flags; + unsigned int update_iter; unsigned int media_rec_slots; };