From e61f5c8b9a57d3e241d2eb34a536bf89e86bbe31 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 25 Jun 2026 10:28:03 -0400 Subject: [PATCH] MT#55283 support call-ID-specific delete Fixes incorrect behaviour of merged calls when doing a full call delete Change-Id: Ic33e97451fce86d213e251464e267595de0f75de --- daemon/call.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/daemon/call.c b/daemon/call.c index d1ade41db..f258b8505 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -6448,6 +6448,11 @@ static void monologue_stop(struct call_monologue *ml, bool stop_media_subscriber } +__attribute__((nonnull(1))) +static int call_delete_by_id(call_t *c, const str *callid, ng_command_ctx_t *ctx, int64_t delete_delay, + bool stats); + + // call must be locked in W and will be unlocked upon returning __attribute__((nonnull(1))) static int call_do_delete_full(call_t *c, int64_t delete_delay) { @@ -6479,6 +6484,10 @@ static int call_delete_full(call_t *c, const str *callid, ng_command_ctx_t *ctx, c->destroyed = rtpe_now; + // short-cut is possible only if there are no call ID aliases + if (c->callid_aliases.length != 0) + return call_delete_by_id(c, callid, ctx, delete_delay, stats); + for (__auto_type i = c->monologues.head; i; i = i->next) { __auto_type ml = i->data; monologue_stop(ml, false); @@ -6526,6 +6535,31 @@ static int call_delete_monologue(call_t *c, const str *callid, struct call_monol } +// call must be locked in W and will be unlocked upon returning +static int call_delete_by_id(call_t *c, const str *callid, ng_command_ctx_t *ctx, int64_t delete_delay, + bool stats) +{ + for (__auto_type i = c->monologues.head; i; i = i->next) { + __auto_type ml = i->data; + if (str_cmp_str(&ml->call_id, callid)) + continue; + + monologue_stop(ml, true); + monologue_delete_iter(ml, delete_delay); + } + + if (!call_monologues_associations_left(c)) + return call_do_delete_full(c, delete_delay); + + rwlock_unlock_w(&c->master_lock); + + redis_update_onekey(c, rtpe_redis_write); + obj_release(c); + + return 0; +} + + // call must be locked in W. // unlocks the call and releases the reference prior to returning, even on error. int call_delete_branch(call_t *c, const str *callid, const str *branch,