func_lock: Add "dialplan locks show" cli command.

For example:

arthur*CLI> dialplan locks show
func_lock locks:
Name                                     Requesters Owner
uls-autoref                              0          (unlocked)
1 total locks listed.

Obviously other potentially useful stats could be added (eg, how many
times there was contention, how many times it failed etc ... but that
would require keeping the stats and I'm not convinced that's worth the
effort.  This was useful to troubleshoot some other issues so submitting
it.

Change-Id: Ib875e56feb49d523300aec5f36c635ed74843a9f
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
This commit is contained in:
Jaco Kroon
2021-05-22 14:29:22 +02:00
committed by George Joseph
parent 19a8383a1f
commit 56c2cc474b

View File

@@ -42,6 +42,7 @@
#include "asterisk/linkedlists.h" #include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h" #include "asterisk/astobj2.h"
#include "asterisk/utils.h" #include "asterisk/utils.h"
#include "asterisk/cli.h"
/*** DOCUMENTATION /*** DOCUMENTATION
<function name="LOCK" language="en_US"> <function name="LOCK" language="en_US">
@@ -430,6 +431,37 @@ static int trylock_read(struct ast_channel *chan, const char *cmd, char *data, c
return 0; return 0;
} }
static char *handle_cli_locks_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
int c = 0;
struct lock_frame* current;
switch (cmd) {
case CLI_INIT:
e->command = "dialplan locks show";
e->usage =
"Usage: dialplan locks show\n"
" List all locks known to func_lock, along with their current status.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, "func_lock locks:\n");
ast_cli(a->fd, "%-40s Requesters Owner\n", "Name");
AST_LIST_LOCK(&locklist);
AST_LIST_TRAVERSE(&locklist, current, entries) {
ast_mutex_lock(&current->mutex);
ast_cli(a->fd, "%-40s %-10d %s\n", current->name, current->requesters,
current->owner ? ast_channel_name(current->owner) : "(unlocked)");
ast_mutex_unlock(&current->mutex);
c++;
}
AST_LIST_UNLOCK(&locklist);
ast_cli(a->fd, "%d total locks listed.\n", c);
return 0;
}
static struct ast_custom_function lock_function = { static struct ast_custom_function lock_function = {
.name = "LOCK", .name = "LOCK",
.read = lock_read, .read = lock_read,
@@ -448,6 +480,8 @@ static struct ast_custom_function unlock_function = {
.read_max = 2, .read_max = 2,
}; };
static struct ast_cli_entry cli_locks_show = AST_CLI_DEFINE(handle_cli_locks_show, "List func_lock locks.");
static int unload_module(void) static int unload_module(void)
{ {
struct lock_frame *current; struct lock_frame *current;
@@ -460,6 +494,8 @@ static int unload_module(void)
ast_custom_function_unregister(&lock_function); ast_custom_function_unregister(&lock_function);
ast_custom_function_unregister(&trylock_function); ast_custom_function_unregister(&trylock_function);
ast_cli_unregister(&cli_locks_show);
AST_LIST_LOCK(&locklist); AST_LIST_LOCK(&locklist);
while ((current = AST_LIST_REMOVE_HEAD(&locklist, entries))) { while ((current = AST_LIST_REMOVE_HEAD(&locklist, entries))) {
int warned = 0; int warned = 0;
@@ -498,6 +534,7 @@ static int load_module(void)
int res = ast_custom_function_register_escalating(&lock_function, AST_CFE_READ); int res = ast_custom_function_register_escalating(&lock_function, AST_CFE_READ);
res |= ast_custom_function_register_escalating(&trylock_function, AST_CFE_READ); res |= ast_custom_function_register_escalating(&trylock_function, AST_CFE_READ);
res |= ast_custom_function_register_escalating(&unlock_function, AST_CFE_READ); res |= ast_custom_function_register_escalating(&unlock_function, AST_CFE_READ);
res |= ast_cli_register(&cli_locks_show);
return res; return res;
} }