Browse Source

MT#57118 Rework the call's deconstruction logic

This commit: 6f0ad0db0f
introduced an improved behavior of the call deconstruction
when dealing with multiple forked legs. But it also
introduced a regression related to TPCC related calls.

This is because it takes into consideration existing
`->viabranches`, which is not efficient in certain cases.

Instead, we just have to ensure, whether there are
other monologues of the call object, which are not directly
"visible" for this branch being cancelled (so they are not directly
associated to that), but they might have own associations
present, which means the call mustn't be globally destoroyed.

Change-Id: I630f2d88ef3b557af3a95816fc2703daccaff374
(cherry picked from commit 0994ffbe75)
(cherry picked from commit 75bef60571)
mr11.3.1
Donat Zenichev 3 years ago
parent
commit
599ffb672b
1 changed files with 33 additions and 3 deletions
  1. +33
    -3
      daemon/call.c

+ 33
- 3
daemon/call.c View File

@ -4313,6 +4313,9 @@ static unsigned int monologue_delete_iter(struct call_monologue *a, int delete_d
if (!call)
return 0;
unsigned int ml_associated_count = g_hash_table_size(a->associated_tags);
unsigned int call_monologues_count = g_queue_get_length(&call->monologues);
GList *associated = g_hash_table_get_values(a->associated_tags);
unsigned int ret = 0;
@ -4331,16 +4334,43 @@ static unsigned int monologue_delete_iter(struct call_monologue *a, int delete_d
ret |= 0x2;
}
// look at all associated tags: cascade deletion to those which have no other associations left
for (GList *l = associated; l; l = l->next) {
/* first, look at all associated tags: cascade deletion to those which have
* no other associations left */
for (GList *l = associated; l; l = l->next)
{
struct call_monologue *b = l->data;
__tags_unassociate(a, b);
if (g_hash_table_size(b->associated_tags) == 0)
ret |= monologue_delete_iter(b, delete_delay);
ret |= monologue_delete_iter(b, delete_delay); /* schedule deletion of B */
else
ret |= 0x1;
}
/* now, if one call object contains some other monologues, which can have own associations,
* not direclty visible for this very monologue,
* then ensure, whether we can afford to destroy the whole call now.
* Maybe some of them still needs a media to flow. */
if (ml_associated_count < call_monologues_count && !(ret & 0x1)) {
for (GList * l = call->monologues.head; l; l = l->next)
{
struct call_monologue * ml = l->data;
/* skip those already checked */
if (g_hash_table_lookup(a->associated_tags, ml))
continue;
/* we are not clearing here monologues not associated with us,
* only checking, if we can afford whole call destroy.
*/
if (g_hash_table_size(ml->associated_tags) > 0) {
ret |= 0x1;
break;
}
}
}
/* otherwise, we have only one call leg, so association monologue A to monologue B (no other branches)
* and we can simple destroy the whole call */
g_list_free(associated);
return ret;
}


Loading…
Cancel
Save