TT#14008 make CLI call iterators lock-free

Change-Id: Id479c66ddd8f8e150bcc30325a356c39e00bb44c
pull/1388/head
Richard Fuchs 4 years ago
parent 10d9be003d
commit 9a149a77fb

@ -188,43 +188,30 @@ static void cli_handler_do(const cli_handler_t *handlers, str *instr,
cw->cw_printf(cw, "%s:" STR_FORMAT "\n", "Unknown or incomplete command:", STR_FMT(instr)); cw->cw_printf(cw, "%s:" STR_FORMAT "\n", "Unknown or incomplete command:", STR_FMT(instr));
} }
static void destroy_own_foreign_calls(int foreign_call, unsigned int uint_keyspace_db) { static void destroy_own_foreign_calls(bool foreign_call, unsigned int uint_keyspace_db) {
struct call *c = NULL; struct call *c = NULL;
struct call_monologue *ml = NULL; struct call_monologue *ml = NULL;
GQueue call_list = G_QUEUE_INIT; GQueue call_list = G_QUEUE_INIT;
GHashTableIter iter;
gpointer key, value;
GList *i; GList *i;
// lock read ITERATE_CALL_LIST_START(CALL_ITERATOR_MAIN, c);
rwlock_lock_r(&rtpe_callhash_lock);
g_hash_table_iter_init(&iter, rtpe_callhash);
while (g_hash_table_iter_next(&iter, &key, &value)) {
c = (struct call*)value;
if (!c) {
continue;
}
// match foreign_call flag // match foreign_call flag
if ((foreign_call != UNDEFINED) && !(foreign_call == IS_FOREIGN_CALL(c))) { if (foreign_call && !IS_FOREIGN_CALL(c))
continue; goto next;
} if (!foreign_call && IS_FOREIGN_CALL(c))
goto next;
// match uint_keyspace_db, if some given // match uint_keyspace_db, if some given
if ((uint_keyspace_db != UNDEFINED) && !(uint_keyspace_db == c->redis_hosted_db)) { if ((uint_keyspace_db != UNDEFINED) && !(uint_keyspace_db == c->redis_hosted_db))
continue; goto next;
}
// increase ref counter // increase ref counter
obj_get(c); obj_get(c);
// save call reference // save call reference
g_queue_push_tail(&call_list, c); g_queue_push_tail(&call_list, c);
} next:;
ITERATE_CALL_LIST_NEXT_END(c);
// unlock read
rwlock_unlock_r(&rtpe_callhash_lock);
// destroy calls // destroy calls
while ((c = g_queue_pop_head(&call_list))) { while ((c = g_queue_pop_head(&call_list))) {
@ -243,15 +230,15 @@ static void destroy_own_foreign_calls(int foreign_call, unsigned int uint_keyspa
} }
static void destroy_all_foreign_calls(void) { static void destroy_all_foreign_calls(void) {
destroy_own_foreign_calls(1, UNDEFINED); destroy_own_foreign_calls(true, UNDEFINED);
} }
static void destroy_all_own_calls(void) { static void destroy_all_own_calls(void) {
destroy_own_foreign_calls(0, UNDEFINED); destroy_own_foreign_calls(false, UNDEFINED);
} }
static void destroy_keyspace_foreign_calls(unsigned int uint_keyspace_db) { static void destroy_keyspace_foreign_calls(unsigned int uint_keyspace_db) {
destroy_own_foreign_calls(1, uint_keyspace_db); destroy_own_foreign_calls(true, uint_keyspace_db);
} }
static void cli_incoming_params_start(str *instr, struct cli_writer *cw) { static void cli_incoming_params_start(str *instr, struct cli_writer *cw) {
@ -653,11 +640,8 @@ static void cli_incoming_list_callid(str *instr, struct cli_writer *cw) {
} }
static void cli_incoming_list_sessions(str *instr, struct cli_writer *cw) { static void cli_incoming_list_sessions(str *instr, struct cli_writer *cw) {
GHashTableIter iter; size_t found = 0;
gpointer key, value; bool all = false, own = false;
str *ptrkey;
struct call *call;
int found_own = 0, found_foreign = 0;
static const char* LIST_ALL = "all"; static const char* LIST_ALL = "all";
static const char* LIST_OWN = "own"; static const char* LIST_OWN = "own";
@ -668,57 +652,39 @@ static void cli_incoming_list_sessions(str *instr, struct cli_writer *cw) {
return; return;
} }
rwlock_lock_r(&rtpe_callhash_lock); if (str_cmp(instr, LIST_ALL) == 0)
all = true;
if (g_hash_table_size(rtpe_callhash)==0) { else if (str_cmp(instr, LIST_OWN) == 0)
cw->cw_printf(cw, "No sessions on this media relay.\n"); own = true;
rwlock_unlock_r(&rtpe_callhash_lock); else if (str_cmp(instr, LIST_FOREIGN) == 0)
{ } // default
else {
// list session for callid
cli_incoming_list_callid(instr, cw);
return; return;
} }
g_hash_table_iter_init (&iter, rtpe_callhash); ITERATE_CALL_LIST_START(CALL_ITERATOR_MAIN, call);
while (g_hash_table_iter_next(&iter, &key, &value)) { if (!all) {
ptrkey = (str*)key; if (IS_FOREIGN_CALL(call) && own)
call = (struct call*)value; goto next;
if (!IS_FOREIGN_CALL(call) && !own)
if (str_cmp(instr, LIST_ALL) == 0) { goto next;
if (!call) {
continue;
}
} else if (str_cmp(instr, LIST_OWN) == 0) {
if (!call || IS_FOREIGN_CALL(call)) {
continue;
} else {
found_own = 1;
}
} else if (str_cmp(instr, LIST_FOREIGN) == 0) {
if (!call || !IS_FOREIGN_CALL(call)) {
continue;
} else {
found_foreign = 1;
}
} else {
// expect callid parameter
break;
} }
found++;
cw->cw_printf(cw, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", ptrkey->s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no"); cw->cw_printf(cw, "callid: %60s | deletionmark:%4s | created:%12i | proxy:%s | redis_keyspace:%i | foreign:%s\n", call->callid.s, call->ml_deleted?"yes":"no", (int)call->created.tv_sec, call->created_from, call->redis_hosted_db, IS_FOREIGN_CALL(call)?"yes":"no");
}
rwlock_unlock_r(&rtpe_callhash_lock);
if (str_cmp(instr, LIST_ALL) == 0) { next:;
; ITERATE_CALL_LIST_NEXT_END(call);
} else if (str_cmp(instr, LIST_OWN) == 0) {
if (!found_own) { if (!found) {
if (all)
cw->cw_printf(cw, "No sessions on this media relay.\n");
else if (own)
cw->cw_printf(cw, "No own sessions on this media relay.\n"); cw->cw_printf(cw, "No own sessions on this media relay.\n");
} else
} else if (str_cmp(instr, LIST_FOREIGN) == 0) {
if (!found_foreign) {
cw->cw_printf(cw, "No foreign sessions on this media relay.\n"); cw->cw_printf(cw, "No foreign sessions on this media relay.\n");
}
} else {
// list session for callid
cli_incoming_list_callid(instr, cw);
} }
return; return;
@ -1093,14 +1059,7 @@ static void cli_incoming_kslist(str *instr, struct cli_writer *cw) {
} }
static void cli_incoming_active_standby(struct cli_writer *cw, bool foreign) { static void cli_incoming_active_standby(struct cli_writer *cw, bool foreign) {
GHashTableIter iter; ITERATE_CALL_LIST_START(CALL_ITERATOR_MAIN, c);
gpointer key, value;
rwlock_lock_r(&rtpe_callhash_lock);
g_hash_table_iter_init(&iter, rtpe_callhash);
while (g_hash_table_iter_next(&iter, &key, &value)) {
struct call *c = value;
rwlock_lock_w(&c->master_lock); rwlock_lock_w(&c->master_lock);
call_make_own_foreign(c, foreign); call_make_own_foreign(c, foreign);
c->last_signal = MAX(c->last_signal, rtpe_now.tv_sec); c->last_signal = MAX(c->last_signal, rtpe_now.tv_sec);
@ -1110,8 +1069,7 @@ static void cli_incoming_active_standby(struct cli_writer *cw, bool foreign) {
} }
rwlock_unlock_w(&c->master_lock); rwlock_unlock_w(&c->master_lock);
redis_update_onekey(c, rtpe_redis_write); redis_update_onekey(c, rtpe_redis_write);
} ITERATE_CALL_LIST_NEXT_END(c);
rwlock_unlock_r(&rtpe_callhash_lock);
cw->cw_printf(cw, "Ok, all calls set to '%s'\n", foreign ? "foreign (standby)" : "owned (active)"); cw->cw_printf(cw, "Ok, all calls set to '%s'\n", foreign ? "foreign (standby)" : "owned (active)");
} }

Loading…
Cancel
Save