diff --git a/funcs/func_groupcount.c b/funcs/func_groupcount.c index 6737af219..a72277a36 100644 --- a/funcs/func_groupcount.c +++ b/funcs/func_groupcount.c @@ -100,7 +100,7 @@ static int group_function_read(struct ast_channel *chan, const char *cmd, { struct ast_group_info *gi = NULL; - ast_app_group_list_lock(); + ast_app_group_list_rdlock(); gi = ast_app_group_list_head(); while (gi) { @@ -158,7 +158,7 @@ static int group_list_function_read(struct ast_channel *chan, const char *cmd, if (!chan) return -1; - ast_app_group_list_lock(); + ast_app_group_list_rdlock(); gi = ast_app_group_list_head(); while (gi) { diff --git a/include/asterisk/app.h b/include/asterisk/app.h index 77e77bfb0..fc763d5f0 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -236,8 +236,11 @@ int ast_app_group_discard(struct ast_channel *chan); /*! Update all group counting for a channel to a new one */ int ast_app_group_update(struct ast_channel *oldchan, struct ast_channel *newchan); -/*! Lock the group count list */ -int ast_app_group_list_lock(void); +/*! Write Lock the group count list */ +int ast_app_group_list_wrlock(void); + +/*! Read Lock the group count list */ +int ast_app_group_list_rdlock(void); /*! Get the head of the group count list */ struct ast_group_info *ast_app_group_list_head(void); diff --git a/main/app.c b/main/app.c index defc0081f..a81831385 100644 --- a/main/app.c +++ b/main/app.c @@ -53,7 +53,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define MAX_OTHER_FORMATS 10 -static AST_LIST_HEAD_STATIC(groups, ast_group_info); +static AST_RWLIST_HEAD_STATIC(groups, ast_group_info); /*! * \brief This function presents a dialtone and reads an extension into 'collect' @@ -874,15 +874,15 @@ int ast_app_group_set_channel(struct ast_channel *chan, const char *data) if (!ast_strlen_zero(category)) len += strlen(category) + 1; - AST_LIST_LOCK(&groups); - AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { + AST_RWLIST_WRLOCK(&groups); + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { if ((gi->chan == chan) && ((ast_strlen_zero(category) && ast_strlen_zero(gi->category)) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))) { - AST_LIST_REMOVE_CURRENT(&groups, list); + AST_RWLIST_REMOVE_CURRENT(&groups, list); free(gi); break; } } - AST_LIST_TRAVERSE_SAFE_END + AST_RWLIST_TRAVERSE_SAFE_END if ((gi = calloc(1, len))) { gi->chan = chan; @@ -892,12 +892,12 @@ int ast_app_group_set_channel(struct ast_channel *chan, const char *data) gi->category = (char *) gi + sizeof(*gi) + strlen(group) + 1; strcpy(gi->category, category); } - AST_LIST_INSERT_TAIL(&groups, gi, list); + AST_RWLIST_INSERT_TAIL(&groups, gi, list); } else { res = -1; } - AST_LIST_UNLOCK(&groups); + AST_RWLIST_UNLOCK(&groups); return res; } @@ -910,12 +910,12 @@ int ast_app_group_get_count(const char *group, const char *category) if (ast_strlen_zero(group)) return 0; - AST_LIST_LOCK(&groups); - AST_LIST_TRAVERSE(&groups, gi, list) { + AST_RWLIST_RDLOCK(&groups); + AST_RWLIST_TRAVERSE(&groups, gi, list) { if (!strcasecmp(gi->group, group) && (ast_strlen_zero(category) || !strcasecmp(gi->category, category))) count++; } - AST_LIST_UNLOCK(&groups); + AST_RWLIST_UNLOCK(&groups); return count; } @@ -933,12 +933,12 @@ int ast_app_group_match_get_count(const char *groupmatch, const char *category) if (regcomp(®exbuf, groupmatch, REG_EXTENDED | REG_NOSUB)) return 0; - AST_LIST_LOCK(&groups); - AST_LIST_TRAVERSE(&groups, gi, list) { + AST_RWLIST_RDLOCK(&groups); + AST_RWLIST_TRAVERSE(&groups, gi, list) { if (!regexec(®exbuf, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || !strcasecmp(gi->category, category))) count++; } - AST_LIST_UNLOCK(&groups); + AST_RWLIST_UNLOCK(&groups); regfree(®exbuf); @@ -949,12 +949,12 @@ int ast_app_group_update(struct ast_channel *old, struct ast_channel *new) { struct ast_group_info *gi = NULL; - AST_LIST_LOCK(&groups); - AST_LIST_TRAVERSE(&groups, gi, list) { + AST_RWLIST_WRLOCK(&groups); + AST_RWLIST_TRAVERSE(&groups, gi, list) { if (gi->chan == old) gi->chan = new; } - AST_LIST_UNLOCK(&groups); + AST_RWLIST_UNLOCK(&groups); return 0; } @@ -963,32 +963,37 @@ int ast_app_group_discard(struct ast_channel *chan) { struct ast_group_info *gi = NULL; - AST_LIST_LOCK(&groups); - AST_LIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { + AST_RWLIST_WRLOCK(&groups); + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&groups, gi, list) { if (gi->chan == chan) { - AST_LIST_REMOVE_CURRENT(&groups, list); + AST_RWLIST_REMOVE_CURRENT(&groups, list); ast_free(gi); } } - AST_LIST_TRAVERSE_SAFE_END - AST_LIST_UNLOCK(&groups); + AST_RWLIST_TRAVERSE_SAFE_END + AST_RWLIST_UNLOCK(&groups); return 0; } -int ast_app_group_list_lock(void) +int ast_app_group_list_wrlock(void) { - return AST_LIST_LOCK(&groups); + return AST_RWLIST_WRLOCK(&groups); +} + +int ast_app_group_list_rdlock(void) +{ + return AST_RWLIST_RDLOCK(&groups); } struct ast_group_info *ast_app_group_list_head(void) { - return AST_LIST_FIRST(&groups); + return AST_RWLIST_FIRST(&groups); } int ast_app_group_list_unlock(void) { - return AST_LIST_UNLOCK(&groups); + return AST_RWLIST_UNLOCK(&groups); } unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen) diff --git a/main/cli.c b/main/cli.c index a3a2532c4..fa30bf3e5 100644 --- a/main/cli.c +++ b/main/cli.c @@ -923,7 +923,7 @@ static int group_show_channels(int fd, int argc, char *argv[]) ast_cli(fd, FORMAT_STRING, "Channel", "Group", "Category"); - ast_app_group_list_lock(); + ast_app_group_list_rdlock(); gi = ast_app_group_list_head(); while (gi) {