From cdba96c09d084a3c33b9d4d9b99df0f196acf06d Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 12 Feb 2026 10:26:15 -0400 Subject: [PATCH] MT#55283 switch subscriptions to intrusive list Change-Id: I4b8839e4d23742f082cb02d4db239d2604d5585e --- daemon/call.c | 184 ++++++++++++++------------------------- daemon/call_interfaces.c | 45 +++------- daemon/cdr.c | 4 +- daemon/cli.c | 12 +-- daemon/codec.c | 14 ++- daemon/janus.c | 2 +- daemon/media_player.c | 2 +- daemon/media_socket.c | 5 +- daemon/redis.c | 10 +-- daemon/ssrc.c | 4 +- include/call.h | 25 +++--- 11 files changed, 112 insertions(+), 195 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index 787c9c36a..7c095b256 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -519,10 +519,8 @@ void kill_calls_timer(GSList *list, const char *url) { if (!media) continue; - for (__auto_type l = media->media_subscribers.head; l; l = l->next) - { - struct media_subscription * ms = l->data; - struct call_monologue * sub_ml = ms->monologue; + IQUEUE_FOREACH(&media->media_subscribers, ms) { + struct call_monologue *sub_ml = ms->monologue; if (!sub_ml->tag.s || !sub_ml->tag.len) continue; @@ -2643,17 +2641,13 @@ static void __update_init_subscribers(struct call_media *media, struct stream_pa /* update all subscribers */ __reset_streams(media); - for (__auto_type l = media->media_subscribers.head; l; l = l->next) - { - struct media_subscription * ms = l->data; - struct call_media * sub_media = ms->media; + IQUEUE_FOREACH(&media->media_subscribers, ms) { + 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; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { struct call_media *sub_media = ms->media; __update_init_subscribers(sub_media, NULL, NULL, opmode, iter); } @@ -3288,8 +3282,8 @@ unsigned int proto_num_ports(unsigned int sp_ports, struct call_media *media, sd } -static int __sub_is_transcoding(const struct media_subscription *ms, gconstpointer dummy) { - return ms->attrs.transcoding ? 0 : 1; +static bool __sub_is_transcoding(const struct media_subscription *ms) { + return ms->attrs.transcoding ? true : false; } /** * Set transcoding flag if any media flows are transcoding, otherwise unset it. @@ -3300,7 +3294,7 @@ static void media_update_transcoding_flag(struct call_media *media) { MEDIA_CLEAR(media, TRANSCODING); - if (t_queue_find_custom(&media->media_subscribers, NULL, __sub_is_transcoding)) + if (i_queue_find(&media->media_subscribers, __sub_is_transcoding)) MEDIA_SET(media, TRANSCODING); } @@ -3826,8 +3820,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q * /* receiver's side, try media subscriptions lookup, fall back to index-based lookup */ receiver_media = NULL; - for (auto_iter(l, sender_media->media_subscriptions.head); l && !receiver_media; l = l->next) { - __auto_type ms = l->data; + IQUEUE_FOREACH(&sender_media->media_subscriptions, ms) { __auto_type r_media = ms->media; if (r_media->monologue != receiver_ml) continue; @@ -3840,6 +3833,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q * continue; /* found it */ receiver_media = r_media; + break; } if (!receiver_media) { ilog(LOG_DEBUG, "No matching media (index: %d) using subscription, just use an index.", sp->index); @@ -4033,22 +4027,21 @@ error_intf: } void media_subscriptions_clear(subscription_q *q) { - t_queue_clear_full(q, media_subscription_free); + i_queue_clear_full(q, media_subscription_free); } -static void __unsubscribe_media_link(struct call_media * which, subscription_list * which_cm_link) +static void __unsubscribe_media_link(struct call_media *which, struct media_subscription *ms) { - struct media_subscription * ms = which_cm_link->data; - struct media_subscription * rev_ms = ms->link->data; - struct call_media * from = ms->media; + struct media_subscription *rev_ms = ms->reverse; + struct call_media *from = ms->media; ilog(LOG_DEBUG, "Unsubscribing media with monologue tag '" STR_FORMAT_M "' (index: %d) " "from media with monologue tag '" STR_FORMAT_M "' (index: %d)", STR_FMT_M(&which->monologue->tag), which->index, STR_FMT_M(&from->monologue->tag), from->index); - t_queue_delete_link(&from->media_subscribers, ms->link); - t_queue_delete_link(&which->media_subscriptions, which_cm_link); + i_queue_delete(&which->media_subscriptions, ms); + i_queue_delete(&from->media_subscribers, rev_ms); t_hash_table_remove(which->media_subscriptions_ht, ms->media); t_hash_table_remove(from->media_subscribers_ht, rev_ms->media); @@ -4059,15 +4052,15 @@ static void __unsubscribe_media_link(struct call_media * which, subscription_lis /** * Unsubscribe one particular media subscriber from this call media. */ -bool __unsubscribe_media(struct call_media * which, struct call_media * from) +bool __unsubscribe_media(struct call_media *which, struct call_media *from) { if (!t_hash_table_is_set(which->media_subscriptions_ht) || !t_hash_table_is_set(from->media_subscribers_ht)) return true; // can happen during shutdown - subscription_list * l = t_hash_table_lookup(which->media_subscriptions_ht, from); + struct media_subscription *ms = t_hash_table_lookup(which->media_subscriptions_ht, from); - if (!l) { + if (!ms) { ilog(LOG_DEBUG, "Media with monologue tag '" STR_FORMAT_M "' (index: %d) " "is not subscribed to media with monologue tag '" STR_FORMAT_M "' " "(index: %d). Cannot remove this media subscriber.", @@ -4077,31 +4070,25 @@ bool __unsubscribe_media(struct call_media * which, struct call_media * from) return false; } - __unsubscribe_media_link(which, l); + __unsubscribe_media_link(which, ms); return true; } /** * Deletes all offer/answer media subscriptions. */ __attribute__((nonnull(1, 2))) -static void __unsubscribe_all_offer_answer_medias(struct call_media * cm, medias_q *medias) { - for (__auto_type l = cm->media_subscribers.head; l; ) - { - struct media_subscription * ms = l->data; - - if (!ms->attrs.offer_answer) { - l = l->next; +static void __unsubscribe_all_offer_answer_medias(struct call_media *cm, medias_q *medias) { + IQUEUE_FOREACH_SAFE_DECL(&cm->media_subscribers, ms); + IQUEUE_FOREACH_SAFE(&cm->media_subscribers, ms) { + if (!ms->attrs.offer_answer) continue; - } - __auto_type next = l->next; - struct call_media * other_cm = ms->media; + struct call_media *other_cm = ms->media; t_queue_push_tail(medias, other_cm); __unsubscribe_media(other_cm, cm); __unsubscribe_media(cm, other_cm); - l = next; } } static void __unsubscribe_medias_from_all(struct call_monologue *ml) { @@ -4111,18 +4098,15 @@ static void __unsubscribe_medias_from_all(struct call_monologue *ml) { if (!media) continue; - for (__auto_type subcription = media->media_subscriptions.head; subcription; ) - { - __auto_type next = subcription->next; - __unsubscribe_media_link(media, subcription); - subcription = next; - } + IQUEUE_FOREACH_SAFE_DECL(&media->media_subscriptions, subscription); + IQUEUE_FOREACH_SAFE(&media->media_subscriptions, subscription) + __unsubscribe_media_link(media, subscription); } } /** * Check whether this monologue medias are subscribed to a single other monologue medias. */ -struct call_monologue * ml_medias_subscribed_to_single_ml(struct call_monologue *ml) { +struct call_monologue *ml_medias_subscribed_to_single_ml(struct call_monologue *ml) { /* detect monologues multiplicity */ struct call_monologue * return_ml = NULL; for (unsigned int i = 0; i < ml->medias->len; i++) @@ -4130,9 +4114,7 @@ struct call_monologue * ml_medias_subscribed_to_single_ml(struct call_monologue struct call_media *media = ml->medias->pdata[i]; if (!media) continue; - for (__auto_type l = media->media_subscriptions.head; l; l = l->next) - { - struct media_subscription * ms = l->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { if (!return_ml) return_ml = ms->monologue; else if (ms->monologue != return_ml) @@ -4144,14 +4126,14 @@ struct call_monologue * ml_medias_subscribed_to_single_ml(struct call_monologue struct media_subscription *__add_media_subscription(struct call_media * which, struct call_media * to, const struct sink_attrs *attrs) { - subscription_list *ret; + struct media_subscription *ret; if ((ret = t_hash_table_lookup(which->media_subscriptions_ht, to))) { ilog(LOG_DEBUG, "Media with monologue tag '" STR_FORMAT_M "' (index: %d) is already subscribed" " to media with monologue tag '" STR_FORMAT_M "' (index: %d)", STR_FMT_M(&which->monologue->tag), which->index, STR_FMT_M(&to->monologue->tag), to->index); - return ret->data; + return ret; } ilog(LOG_DEBUG, "Subscribing media with monologue tag '" STR_FORMAT_M "' (index: %d) " @@ -4170,25 +4152,25 @@ struct media_subscription *__add_media_subscription(struct call_media * which, s /* preserve attributes if they were present previously */ if (attrs) { - which_ms->attrs = * attrs; - to_rev_ms->attrs = * attrs; + which_ms->attrs = *attrs; + to_rev_ms->attrs = *attrs; } /* keep offer-answer subscriptions first in the list */ if (!attrs || !attrs->offer_answer) { - t_queue_push_tail(&which->media_subscriptions, which_ms); - t_queue_push_tail(&to->media_subscribers, to_rev_ms); - which_ms->link = to->media_subscribers.tail; - to_rev_ms->link = which->media_subscriptions.tail; + i_queue_push_tail(&which->media_subscriptions, which_ms); + i_queue_push_tail(&to->media_subscribers, to_rev_ms); + which_ms->reverse = to_rev_ms; + to_rev_ms->reverse = which_ms; } else { - t_queue_push_head(&which->media_subscriptions, which_ms); - t_queue_push_head(&to->media_subscribers, to_rev_ms); - which_ms->link = to->media_subscribers.head; - to_rev_ms->link = which->media_subscriptions.head; + i_queue_push_head(&which->media_subscriptions, which_ms); + i_queue_push_head(&to->media_subscribers, to_rev_ms); + which_ms->reverse = to_rev_ms; + to_rev_ms->reverse = which_ms; } - t_hash_table_insert(which->media_subscriptions_ht, to, to_rev_ms->link); - t_hash_table_insert(to->media_subscribers_ht, which, which_ms->link); + t_hash_table_insert(which->media_subscriptions_ht, to, which_ms); + t_hash_table_insert(to->media_subscribers_ht, which, to_rev_ms); return to_rev_ms; } @@ -4235,19 +4217,14 @@ static struct media_subscription *__subscribe_medias_both_ways(struct call_media * Checks if given media is in subscriptions/subscribers HT of opposite media. */ struct media_subscription *call_get_media_subscription(subscription_ht ht, struct call_media * cm) { - subscription_list *l = t_hash_table_lookup(ht, cm); - if (!l) - return NULL; - return l->data; + return t_hash_table_lookup(ht, cm); } /** * Retrieve top most media subscription of given media. */ -struct media_subscription *call_media_get_top_ms(struct call_media * cm) { - if (cm->media_subscriptions.head) - return cm->media_subscriptions.head->data; - return NULL; +struct media_subscription *call_media_get_top_ms(struct call_media *cm) { + return cm->media_subscriptions.head; } /** @@ -4261,9 +4238,9 @@ struct media_subscription *call_ml_get_top_ms(struct call_monologue *ml) { struct call_media * media = ml->medias->pdata[i]; if (!media) continue; - __auto_type subcription = media->media_subscriptions.head; - if (subcription) - return subcription->data; + __auto_type subscription = media->media_subscriptions.head; + if (subscription) + return subscription; } return NULL; } @@ -4473,9 +4450,7 @@ int monologue_subscribe_request(const subscription_q *srms, struct call_monologu __call_monologue_init_from_flags(dst_ml, NULL, flags); g_auto(GQueue) mls = G_QUEUE_INIT; /* to avoid duplications */ - for (auto_iter(sl, srms->head); sl; sl = sl->next) - { - struct media_subscription *ms = sl->data; + IQUEUE_FOREACH(srms, ms) { struct call_monologue *src_ml = ms->monologue; if (!src_ml) continue; @@ -4514,10 +4489,7 @@ int monologue_subscribe_answer(struct call_monologue *dst_ml, sdp_ng_flags *flag /* set src_media based on subscription (assuming it is one-to-one) * TODO: this should probably be reworked to support one-to-multi subscriptions. */ - __auto_type src_ml_media_it = dst_media->media_subscriptions.head; - if (!src_ml_media_it) - continue; - struct media_subscription *ms = src_ml_media_it->data; + __auto_type ms = dst_media->media_subscriptions.head; if (!ms) continue; struct call_media *src_media = ms->media; @@ -4580,9 +4552,7 @@ int monologue_subscribe_answer(struct call_monologue *dst_ml, sdp_ng_flags *flag continue; /* TODO: probably we should take care about subscribers as well? */ - for (__auto_type sub = dst_media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; + IQUEUE_FOREACH(&dst_media->media_subscriptions, ms) { if (!g_queue_find(&mls, ms->monologue)) { media_update_transcoding_flag(ms->media); update_init_subscribers(ms->media, NULL, NULL, flags->opmode); @@ -4609,17 +4579,13 @@ int monologue_unsubscribe(struct call_monologue *dst_ml, sdp_ng_flags *flags) { __media_unconfirm(media, "media unsubscribe"); /* TODO: should we care about subscribers as well? */ - for (__auto_type l = media->media_subscriptions.head; l; ) - { - __auto_type next = l->next; - struct media_subscription * ms = l->data; - struct call_media * src_media = ms->media; + IQUEUE_FOREACH_SAFE_DECL(&media->media_subscriptions, ms); + IQUEUE_FOREACH_SAFE(&media->media_subscriptions, ms) { + struct call_media *src_media = ms->media; __media_unconfirm(src_media, "media unsubscribe"); - __unsubscribe_media_link(media, l); + __unsubscribe_media_link(media, ms); update_init_subscribers(src_media, NULL, NULL, flags->opmode); - - l = next; } update_init_subscribers(media, NULL, NULL, flags->opmode); @@ -4892,16 +4858,12 @@ void call_destroy(call_t *c) { if (!md) continue; - for (__auto_type ll = md->media_subscriptions.head; ll; ll = ll->next) - { - struct media_subscription * ms = ll->data; + IQUEUE_FOREACH(&md->media_subscriptions, ms) { ilog(LOG_INFO, "--- subscribed to media with monologue tag '" STR_FORMAT_M "' (index: %d)", STR_FMT_M(&ms->monologue->tag), ms->media->index); } - for (__auto_type ll = md->media_subscribers.head; ll; ll = ll->next) - { - struct media_subscription * ms = ll->data; + IQUEUE_FOREACH(&md->media_subscribers, ms) { ilog(LOG_INFO, "--- subscription for media with monologue tag '" STR_FORMAT_M "' (index: %d)", STR_FMT_M(&ms->monologue->tag), ms->media->index); } @@ -5068,8 +5030,8 @@ void call_media_free(struct call_media **mdp) { t_queue_clear_full(&md->dtmf_send, dtmf_event_free); t_hash_table_destroy_ptr(&md->media_subscribers_ht); t_hash_table_destroy_ptr(&md->media_subscriptions_ht); - t_queue_clear_full(&md->media_subscribers, media_subscription_free); - t_queue_clear_full(&md->media_subscriptions, media_subscription_free); + i_queue_clear_full(&md->media_subscribers, media_subscription_free); + i_queue_clear_full(&md->media_subscriptions, media_subscription_free); codec_handlers_free(md); codec_handler_free(&md->t38_handler); t38_gateway_put(&md->t38_gateway); @@ -5568,16 +5530,10 @@ void dialogue_unconfirm(struct call_monologue *ml, const char *reason) { struct call_media *media = ml->medias->pdata[i]; if (!media) continue; - for (__auto_type l = media->media_subscriptions.head; l; l = l->next) - { - struct media_subscription * ms = l->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) __media_unconfirm(ms->media, reason); - } - for (__auto_type l = media->media_subscribers.head; l; l = l->next) - { - struct media_subscription * ms = l->data; + IQUEUE_FOREACH(&media->media_subscribers, ms) __media_unconfirm(ms->media, reason); - } } } @@ -5825,9 +5781,7 @@ have_dialogue: struct call_media *media = ret->medias->pdata[i]; if (!media) continue; - for (__auto_type l = media->media_subscriptions.head; l; l = l->next) - { - struct media_subscription * ms = l->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { if (!ms->attrs.offer_answer) continue; if (!os) @@ -5894,9 +5848,7 @@ static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call, if (!media) continue; /* try to find tt in subscriptions of ft */ - for (__auto_type l = media->media_subscriptions.head; l; l = l->next) - { - struct media_subscription * ms = l->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { if (ms->monologue && ms->monologue == tt) goto done; } @@ -5919,7 +5871,7 @@ static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call, struct call_media *media = tt->medias->pdata[i]; if (!media || !media->media_subscriptions.head) continue; - struct media_subscription * ms = media->media_subscriptions.head->data; + struct media_subscription *ms = media->media_subscriptions.head; if (ms->monologue) { ft = ms->monologue; __C_DBG("Found existing monologue '" STR_FORMAT "' for this side, by lookup of other side subscriptions", @@ -6019,9 +5971,7 @@ static void monologue_stop(struct call_monologue *ml, bool stop_media_subsribers struct call_media *media = ml->medias->pdata[i]; if (!media) continue; - for (__auto_type l = media->media_subscribers.head; l; l = l->next) - { - struct media_subscription * ms = l->data; + IQUEUE_FOREACH(&media->media_subscribers, ms) { media_stop(ms->media); if (!g_queue_find(&mls, ms->monologue)) { __monologue_stop(ms->monologue); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 58553a856..1de45a01f 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -3004,11 +3004,7 @@ static void ng_stats_monologue(ng_command_ctx_t *ctx, parser_arg dict, const str if (!media) continue; - for (__auto_type subscription = media->media_subscriptions.head; - subscription; - subscription = subscription->next) - { - struct media_subscription * ms = subscription->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { if (!g_queue_find(&mls_subscriptions, ms->monologue)) { parser_arg sub1 = parser->list_add_dict(b_subscriptions); parser->dict_add_str(sub1, "tag", &ms->monologue->tag); @@ -3016,11 +3012,7 @@ static void ng_stats_monologue(ng_command_ctx_t *ctx, parser_arg dict, const str g_queue_push_tail(&mls_subscriptions, ms->monologue); } } - for (__auto_type subscriber = media->media_subscribers.head; - subscriber; - subscriber = subscriber->next) - { - struct media_subscription * ms = subscriber->data; + IQUEUE_FOREACH(&media->media_subscribers, ms) { if (!g_queue_find(&mls_subscribers, ms->monologue)) { parser_arg sub1 = parser->list_add_dict(b_subscribers); parser->dict_add_str(sub1, "tag", &ms->monologue->tag); @@ -3204,11 +3196,7 @@ stats: if (!media) continue; - for (__auto_type subscription = media->media_subscriptions.head; - subscription; - subscription = subscription->next) - { - struct media_subscription * ms = subscription->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { if (!g_queue_find(&mls, ms->monologue)) { ng_stats_monologue(ctx, tags, ms->monologue, totals, ssrc); g_queue_push_tail(&mls, ms->monologue); @@ -3456,7 +3444,7 @@ void add_media_to_sub_list(subscription_q *q, struct call_media *media, struct c struct media_subscription *ms = g_new0(__typeof(*ms), 1); ms->media = media; ms->monologue = ml; - t_queue_push_tail(q, ms); + i_queue_push_tail(q, ms); } static const char *media_block_match_mult(call_t **call, subscription_q *medias, sdp_ng_flags *flags, ng_command_ctx_t *ctx) @@ -3796,16 +3784,16 @@ static const char *call_block_silence_media(ng_command_ctx_t *ctx, bool on_off, struct call_media * ml_media = monologue->medias->pdata[j]; if (!ml_media) continue; - subscription_list * ll = t_hash_table_lookup(ml_media->media_subscriptions_ht, sink_md); + __auto_type ll = t_hash_table_lookup(ml_media->media_subscriptions_ht, sink_md); if (ll) { found_subscriptions = true; - G_STRUCT_MEMBER(bool, &ll->data->attrs, attr_offset) = on_off; + G_STRUCT_MEMBER(bool, &ll->attrs, attr_offset) = on_off; ilog(LOG_INFO, "%s directional media flow: " "monologue tag '" STR_FORMAT_M "' -> '" STR_FORMAT_M "' / " "media index '%d' -> '%d'", ucase_verb, - STR_FMT_M(&monologue->tag), STR_FMT_M(&ll->data->monologue->tag), - ml_media->index, ll->data->media->index); + STR_FMT_M(&monologue->tag), STR_FMT_M(&ll->monologue->tag), + ml_media->index, ll->media->index); } } sinks = true; @@ -3821,10 +3809,8 @@ static const char *call_block_silence_media(ng_command_ctx_t *ctx, bool on_off, if (!ml_media) continue; - for (__auto_type sub = ml_media->media_subscribers.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; - struct call_media * sub_md = ms->media; + IQUEUE_FOREACH(&ml_media->media_subscribers, ms) { + struct call_media *sub_md = ms->media; if (!sub_md || (flags.all == ALL_OFFER_ANSWER && !ms->attrs.offer_answer) || @@ -4089,9 +4075,7 @@ found: struct call_media * ms_media_sink = NULL; - for (__auto_type ll = ml_media->media_subscribers.head; ll; ll = ll->next) - { - struct media_subscription * ms = ll->data; + IQUEUE_FOREACH(&ml_media->media_subscribers, ms) { ms_media_sink = ms->media; if (!ms_media_sink || ms_media_sink->type_id != MT_AUDIO) continue; @@ -4181,7 +4165,7 @@ const char *call_subscribe_request_ng(ng_command_ctx_t *ctx) { g_auto(sdp_ng_flags) flags; char rand_buf[65]; g_autoptr(call_t) call = NULL; - g_auto(subscription_q) srms = TYPED_GQUEUE_INIT; + g_auto(subscription_q) srms = IQUEUE_INIT; g_auto(str) sdp_out = STR_NULL; parser_arg output = ctx->resp; const ng_parser_t *parser = ctx->parser_ctx.parser; @@ -4232,7 +4216,7 @@ const char *call_subscribe_request_ng(ng_command_ctx_t *ctx) { * TODO: deprecate it, since initially added for monologue subscriptions. */ if (srms.length == 1) { - struct media_subscription *ms = srms.head->data; + struct media_subscription *ms = srms.head; struct call_monologue *source_ml = ms->monologue; parser->dict_add_str_dup(output, "from-tag", &source_ml->tag); } @@ -4242,8 +4226,7 @@ const char *call_subscribe_request_ng(ng_command_ctx_t *ctx) { media_labels = parser->dict_add_dict(output, "media-labels"); } parser_arg from_list = parser->dict_add_list(output, "from-tags"); - for (__auto_type l = srms.head; l; l = l->next) { - struct media_subscription *ms = l->data; + IQUEUE_FOREACH(&srms, ms) { struct call_monologue *source_ml = ms->monologue; parser->list_add_str_dup(from_list, &source_ml->tag); if (tag_medias.gen) { diff --git a/daemon/cdr.c b/daemon/cdr.c index 9358d4bc1..b1737535a 100644 --- a/daemon/cdr.c +++ b/daemon/cdr.c @@ -84,9 +84,7 @@ void cdr_update_entry(call_t * c) { if (!media) continue; - for (__auto_type sub = media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { if (!g_queue_find(&mls, ms->monologue)) { g_string_append_printf(cdr, "ml%i_remote_tag=%s, ", cdrlinecnt, ms->monologue->tag.s); g_queue_push_tail(&mls, ms->monologue); diff --git a/daemon/cli.c b/daemon/cli.c index 32358bf61..12220ae94 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -753,10 +753,8 @@ static void cli_list_tag_info(struct cli_writer *cw, struct call_monologue *ml) if (!media) continue; - for (__auto_type sub = media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; - struct call_media * sub_media = ms->media; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { + struct call_media *sub_media = ms->media; if (!sub_media) continue; @@ -764,10 +762,8 @@ static void cli_list_tag_info(struct cli_writer *cw, struct call_monologue *ml) STR_FMT_M(&ms->monologue->tag), sub_media->index); } - for (__auto_type sub = media->media_subscribers.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; - struct call_media * sub_media = ms->media; + IQUEUE_FOREACH(&media->media_subscribers, ms) { + struct call_media *sub_media = ms->media; if (!sub_media) continue; diff --git a/daemon/codec.c b/daemon/codec.c index f081d4773..5c17546ec 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1441,7 +1441,7 @@ void __codec_handlers_update(struct call_media *receiver, struct call_media *sin return; /* required for updating the transcoding attrs of subscriber */ - struct media_subscription * ms = call_get_media_subscription(receiver->media_subscribers_ht, sink); + struct media_subscription *ms = call_get_media_subscription(receiver->media_subscribers_ht, sink); ilogs(codec, LOG_DEBUG, "Setting up codec handlers for " STR_FORMAT_M " #%u -> " STR_FORMAT_M " #%u", STR_FMT_M(&monologue->tag), receiver->index, @@ -4928,10 +4928,8 @@ void codec_update_all_handlers(struct call_monologue *ml) { if (!source_media) continue; - for (__auto_type sub = source_media->media_subscribers.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; - struct call_media * sink_media = ms->media; + IQUEUE_FOREACH(&source_media->media_subscribers, ms) { + struct call_media *sink_media = ms->media; if (!sink_media) continue; @@ -4950,10 +4948,8 @@ void codec_update_all_source_handlers(struct call_monologue *ml, const sdp_ng_fl if (!sink_media) continue; - for (__auto_type sub = sink_media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; - struct call_media * source_media = ms->media; + IQUEUE_FOREACH(&sink_media->media_subscriptions, ms) { + struct call_media *source_media = ms->media; if (!source_media) continue; diff --git a/daemon/janus.c b/daemon/janus.c index b1084ce0a..f277d8e36 100644 --- a/daemon/janus.c +++ b/daemon/janus.c @@ -555,7 +555,7 @@ static const char *janus_videoroom_join(struct websocket_message *wm, struct jan else { // subscriber - g_auto(subscription_q) srms = TYPED_GQUEUE_INIT; + g_auto(subscription_q) srms = IQUEUE_INIT; // get single feed ID if there is one if (json_reader_read_member(reader, "feed")) { diff --git a/daemon/media_player.c b/daemon/media_player.c index bee6ad08c..eb2a6298b 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -1596,7 +1596,7 @@ check_next: bf_set(&media->media_flags, MEDIA_FLAG_FAKE_SENDRECV); if (media->media_subscriptions.head) { - __auto_type sub = media->media_subscriptions.head->data; + __auto_type sub = media->media_subscriptions.head; __auto_type sub_m = sub->media; /* mark real state of originators media (no flag set - inactive, real_sendonly - sendonly) */ if (MEDIA_ISSET(sub_m, RECV)) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index c8c940c80..fabbd0c43 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -3744,10 +3744,7 @@ out: } if (phc->unkernelize_subscriptions) { g_auto(GQueue) mls = G_QUEUE_INIT; /* to avoid duplications */ - for (__auto_type sub = phc->mp.media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; - + IQUEUE_FOREACH(&phc->mp.media->media_subscriptions, ms) { if (!g_queue_find(&mls, ms->monologue)) { for (unsigned int k = 0; k < ms->monologue->medias->len; k++) { diff --git a/daemon/redis.c b/daemon/redis.c index c1a733541..082b070ea 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -1891,11 +1891,7 @@ static struct media_subscription *__find_media_subscriber(struct call_media *med struct call_monologue * find_ml = sink->media->monologue; - for (__auto_type subscriber = media->media_subscribers.head; - subscriber; - subscriber = subscriber->next) - { - struct media_subscription * ms = subscriber->data; + IQUEUE_FOREACH(&media->media_subscribers, ms) { if (find_ml == ms->monologue) return ms; } @@ -2716,9 +2712,7 @@ static str redis_encode_json(ng_parser_ctx_t *ctx, call_t *c, void **to_free) { snprintf(tmp, sizeof(tmp), "media-subscriptions-%u", media->unique_id); inner = parser->dict_add_list_dup(root, tmp); - for (__auto_type sub = media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { JSON_ADD_LIST_STRING("%u/%u/%u/%u", ms->media->unique_id, ms->attrs.offer_answer, diff --git a/daemon/ssrc.c b/daemon/ssrc.c index 4ef96e88c..0b9880854 100644 --- a/daemon/ssrc.c +++ b/daemon/ssrc.c @@ -329,9 +329,7 @@ static struct ssrc_entry_call *hunt_ssrc(struct call_media *media, uint32_t ssrc if (!media) return NULL; - for (__auto_type sub = media->media_subscriptions.head; sub; sub = sub->next) - { - struct media_subscription * ms = sub->data; + IQUEUE_FOREACH(&media->media_subscriptions, ms) { struct ssrc_entry_call *e = find_ssrc(ssrc, &ms->media->ssrc_hash_in, NULL); if (e) return e; diff --git a/include/call.h b/include/call.h index 49a19061c..ab8688aa7 100644 --- a/include/call.h +++ b/include/call.h @@ -332,10 +332,9 @@ struct media_subscription; TYPED_GHASHTABLE(codecs_ht, void, rtp_payload_type, g_direct_hash, g_direct_equal, NULL, NULL) TYPED_GHASHTABLE(codec_names_ht, str, GQueue, str_case_hash, str_case_equal, str_free, g_queue_free) TYPED_GHASHTABLE_LOOKUP_INSERT(codec_names_ht, str_free, g_queue_new) -TYPED_GQUEUE(subscription, struct media_subscription) TYPED_DIRECT_FUNCS(media_direct_hash, media_direct_eq, struct call_media) -TYPED_GHASHTABLE(subscription_ht, struct call_media, subscription_list, media_direct_hash, media_direct_eq, - NULL, NULL) +TYPED_GHASHTABLE(subscription_ht, struct call_media, struct media_subscription, + media_direct_hash, media_direct_eq, NULL, NULL) TYPED_GHASHTABLE(media_id_ht, str, struct call_media, str_hash, str_equal, NULL, NULL) TYPED_GHASHTABLE(pt_media_ht, void, struct call_media, g_direct_hash, g_direct_equal, NULL, NULL) @@ -480,6 +479,19 @@ struct extmap_ops { extern const struct extmap_ops extmap_ops_long; + +struct media_subscription { + IQUEUE_LINK link; + struct call_media *media; /* media itself */ + struct call_monologue *monologue; /* whom media belongs to */ + struct sink_attrs attrs; /* attributes to passed to a sink */ + struct media_subscription *reverse; // opposite (subscription -> subscriber / vice versa) +}; + +typedef IQUEUE_TYPE(struct media_subscription, link) subscription_q; + + + /** * Protected by call->master_lock, except the RO elements. * @@ -579,13 +591,6 @@ TYPED_GQUEUE(medias, struct call_media) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(medias_q, medias_q_clear) -struct media_subscription { - struct call_media * media; /* media itself */ - struct call_monologue * monologue; /* whom media belongs to */ - struct sink_attrs attrs; /* attributes to passed to a sink */ - subscription_list * link; /* TODO: is this still really needed? */ -}; - /** * Half a dialogue. * Protected by call->master_lock, except the RO elements.