Browse Source

MT#55984 introduce `associated_tags` hash table

Keep track which tags (monologues) were created together as part of an
offer/answer exchange with a separate hash table, regardless of whether
these monologues actually have tagged names or are just nameless
branches.

Change-Id: I60aa114c8caf6ecdff4705e3399f60190d04dda6
pull/1577/head
Richard Fuchs 3 years ago
parent
commit
6f0ad0db0f
3 changed files with 50 additions and 0 deletions
  1. +27
    -0
      daemon/call.c
  2. +22
    -0
      daemon/redis.c
  3. +1
    -0
      include/call.h

+ 27
- 0
daemon/call.c View File

@ -3737,6 +3737,7 @@ static void __call_free(void *p) {
g_queue_clear(&m->medias);
g_hash_table_destroy(m->other_tags);
g_hash_table_destroy(m->associated_tags);
g_hash_table_destroy(m->branches);
g_hash_table_destroy(m->media_ids);
free_ssrc_hash(&m->ssrc_hash);
@ -3932,6 +3933,7 @@ struct call_monologue *__monologue_create(struct call *call) {
ret->call = call;
ret->created = rtpe_now.tv_sec;
ret->other_tags = g_hash_table_new(str_hash, str_equal);
ret->associated_tags = g_hash_table_new(g_direct_hash, g_direct_equal);
ret->branches = g_hash_table_new(str_hash, str_equal);
ret->media_ids = g_hash_table_new(str_hash, str_equal);
ret->ssrc_hash = create_ssrc_hash_call();
@ -4037,6 +4039,16 @@ void call_media_unkernelize(struct call_media *media) {
}
}
/* must be called with call->master_lock held in W */
static void __tags_unassociate_all(struct call_monologue *a) {
GHashTableIter iter;
g_hash_table_iter_init(&iter, a->associated_tags);
struct call_monologue *b;
while (g_hash_table_iter_next(&iter, (void **) &b, NULL))
g_hash_table_remove(b->associated_tags, a);
g_hash_table_remove_all(a->associated_tags);
}
/* must be called with call->master_lock held in W */
static void __monologue_destroy(struct call_monologue *monologue, bool recurse) {
struct call *call;
@ -4049,6 +4061,7 @@ static void __monologue_destroy(struct call_monologue *monologue, bool recurse)
STR_FMT0(&monologue->viabranch));
__monologue_unkernelize(monologue);
__tags_unassociate_all(monologue);
g_hash_table_remove(call->tags, &monologue->tag);
if (monologue->viabranch.s)
@ -4096,6 +4109,12 @@ static void __monologue_destroy(struct call_monologue *monologue, bool recurse)
monologue->deleted = 0;
}
/* must be called with call->master_lock held in W */
static void __tags_unassociate(struct call_monologue *a, struct call_monologue *b) {
g_hash_table_remove(a->associated_tags, b);
g_hash_table_remove(b->associated_tags, a);
}
/* must be called with call->master_lock held in W */
int monologue_destroy(struct call_monologue *ml) {
struct call *c = ml->call;
@ -4149,6 +4168,12 @@ struct call_monologue *call_get_or_create_monologue(struct call *call, const str
return ret;
}
/* must be called with call->master_lock held in W */
static void __tags_associate(struct call_monologue *a, struct call_monologue *b) {
g_hash_table_insert(a->associated_tags, b, b);
g_hash_table_insert(b->associated_tags, a, a);
}
/* must be called with call->master_lock held in W */
static int call_get_monologue_new(struct call_monologue *dialogue[2], struct call *call,
const str *fromtag, const str *totag,
@ -4242,6 +4267,7 @@ ok_check_tag:
break; // there should only be one
// XXX check if there's more than a one-to-one mapping here?
}
__tags_associate(ret, os);
dialogue[0] = ret;
dialogue[1] = os;
return 0;
@ -4320,6 +4346,7 @@ tag_setup:
done:
__monologue_unkernelize(ft);
dialogue_unkernelize(ft);
__tags_associate(ft, tt);
dialogue[0] = ft;
dialogue[1] = tt;
return 0;


+ 22
- 0
daemon/redis.c View File

@ -1721,6 +1721,16 @@ static int json_link_tags(struct call *c, struct redis_list *tags, struct redis_
}
g_queue_clear(&q);
if (json_build_list(&q, c, "associated_tags", i, tags, root_reader))
return -1;
for (l = q.head; l; l = l->next) {
other_ml = l->data;
if (!other_ml)
return -1;
g_hash_table_insert(ml->associated_tags, other_ml, other_ml);
}
g_queue_clear(&q);
if (json_build_list(&q, c, "branches", i, tags, root_reader))
return -1;
for (l = q.head; l; l = l->next) {
@ -2509,6 +2519,18 @@ char* redis_encode_json(struct call *c) {
g_list_free(k);
k = g_hash_table_get_values(ml->associated_tags);
snprintf(tmp, sizeof(tmp), "associated_tags-%u", ml->unique_id);
json_builder_set_member_name(builder, tmp);
json_builder_begin_array (builder);
for (m = k; m; m = m->next) {
ml2 = m->data;
JSON_ADD_STRING("%u",ml2->unique_id);
}
json_builder_end_array (builder);
g_list_free(k);
k = g_hash_table_get_values(ml->branches);
snprintf(tmp, sizeof(tmp), "branches-%u", ml->unique_id);
json_builder_set_member_name(builder, tmp);


+ 1
- 0
include/call.h View File

@ -487,6 +487,7 @@ struct call_monologue {
struct timeval terminated; /* for CDR */
enum termination_reason term_reason;
const struct logical_intf *logical_intf;
GHashTable *associated_tags;
GHashTable *other_tags;
GHashTable *branches;
GQueue subscriptions; /* who am I subscribed to (sources) */


Loading…
Cancel
Save