Index: include/asterisk/linkedlists.h =================================================================== --- include/asterisk/linkedlists.h (revision 8705) +++ include/asterisk/linkedlists.h (working copy) @@ -313,6 +313,16 @@ if (!__list_next) \ (head)->last = __list_prev; +#define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \ + if (__list_prev) { \ + (elm)->field.next = __list_prev->field.next; \ + __list_prev->field.next = elm; \ + } else { \ + (elm)->field.next = (head)->first; \ + (head)->first = (elm); \ + } \ +} while (0) + /*! \brief Closes a safe loop traversal block. */ Index: include/asterisk/cli.h =================================================================== --- include/asterisk/cli.h (revision 8705) +++ include/asterisk/cli.h (working copy) @@ -29,6 +29,8 @@ #include +#include "asterisk/linkedlists.h" + void ast_cli(int fd, char *fmt, ...) __attribute__ ((format (printf, 2, 3))); @@ -67,10 +69,10 @@ until a NULL is returned. */ char *(*generator)(const char *line, const char *word, int pos, int n); - /*! For linking */ - struct ast_cli_entry *next; /*! For keeping track of usage */ int inuse; + /*! For linking */ + AST_LIST_ENTRY(ast_cli_entry) list; }; Index: cli.c =================================================================== --- cli.c (revision 8705) +++ cli.c (working copy) @@ -77,10 +77,8 @@ } } -AST_MUTEX_DEFINE_STATIC(clilock); +static AST_LIST_HEAD_STATIC(helpers, ast_cli_entry); -struct ast_cli_entry *helpers = NULL; - static char load_help[] = "Usage: load \n" " Loads the specified module into Asterisk.\n"; @@ -948,7 +946,7 @@ int match; struct ast_cli_entry *e=NULL; - for (e=helpers;e;e=e->next) { + AST_LIST_TRAVERSE(&helpers, e, list) { match = 1; for (y=0;match && cmds[y]; y++) { if (!e->cmda[y] && !exact) @@ -1027,72 +1025,47 @@ int ast_cli_unregister(struct ast_cli_entry *e) { - struct ast_cli_entry *cur, *l=NULL; - ast_mutex_lock(&clilock); - cur = helpers; - while(cur) { - if (e == cur) { - if (e->inuse) { - ast_log(LOG_WARNING, "Can't remove command that is in use\n"); - } else { - /* Rewrite */ - if (l) - l->next = e->next; - else - helpers = e->next; - e->next = NULL; - break; - } - } - l = cur; - cur = cur->next; + if (e->inuse) { + ast_log(LOG_WARNING, "Can't remove command that is in use\n"); + } else { + AST_LIST_LOCK(&helpers); + AST_LIST_REMOVE(&helpers, e, list); + AST_LIST_UNLOCK(&helpers); } - ast_mutex_unlock(&clilock); return 0; } int ast_cli_register(struct ast_cli_entry *e) { - struct ast_cli_entry *cur, *l=NULL; + struct ast_cli_entry *cur; char fulle[80] ="", fulltst[80] =""; static int len; - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); join2(fulle, sizeof(fulle), e->cmda); if (find_cli(e->cmda, -1)) { - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle); return -1; } - for (cur = helpers; cur; cur = cur->next) { + AST_LIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) { join2(fulltst, sizeof(fulltst), cur->cmda); len = strlen(fulltst); if (strlen(fulle) < len) len = strlen(fulle); if (strncasecmp(fulle, fulltst, len) < 0) { - if (l) { - e->next = l->next; - l->next = e; - } else { - e->next = helpers; - helpers = e; - } + AST_LIST_INSERT_BEFORE_CURRENT(&helpers, e, list); break; } - l = cur; } + AST_LIST_TRAVERSE_SAFE_END - if (!cur) { - if (l) - l->next = e; - else - helpers = e; - e->next = NULL; - } + if (!cur) + AST_LIST_INSERT_TAIL(&helpers, e, list); - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); return 0; } @@ -1124,7 +1097,7 @@ char *fullcmd = NULL; struct ast_cli_entry *e, *e1, *e2; e1 = builtins; - e2 = helpers; + e2 = AST_LIST_FIRST(&helpers); if (match) join(matchstr, sizeof(matchstr), match, 0); while(e1->cmda[0] || e2) { @@ -1138,7 +1111,7 @@ e = e2; fullcmd = fullcmd2; /* Increment by going to next */ - e2 = e2->next; + e2 = AST_LIST_NEXT(e2, list); } else { /* Use e1 */ e = e1; @@ -1319,9 +1292,9 @@ if ((dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws))) { join(matchstr, sizeof(matchstr), argv, tws); if (lock) - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); e1 = builtins; - e2 = helpers; + e2 = AST_LIST_FIRST(&helpers); while(e1->cmda[0] || e2) { if (e2) join(fullcmd2, sizeof(fullcmd2), e2->cmda, tws); @@ -1333,7 +1306,7 @@ e = e2; fullcmd = fullcmd2; /* Increment by going to next */ - e2 = e2->next; + e2 = AST_LIST_NEXT(e2, list); } else { /* Use e1 */ e = e1; @@ -1352,7 +1325,7 @@ matchnum++; if (matchnum > state) { if (lock) - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); free(dup); return strdup(res); } @@ -1365,7 +1338,7 @@ fullcmd = e->generator(matchstr, word, (!ast_strlen_zero(word) ? (x - 1) : (x)), state); if (fullcmd) { if (lock) - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); free(dup); return fullcmd; } @@ -1373,7 +1346,7 @@ } if (lock) - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); free(dup); } return NULL; @@ -1400,11 +1373,11 @@ /* We need at least one entry, or ignore */ if (x > 0) { - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); e = find_cli(argv, 0); if (e) e->inuse++; - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); if (e) { switch(e->handler(fd, x, argv)) { case RESULT_SHOWUSAGE: @@ -1414,9 +1387,9 @@ } else ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv)); if (e) { - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); e->inuse--; - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); } } free(dup);