Use read/write lock based lists for group counting.
authorJoshua Colp <jcolp@digium.com>
Wed, 13 Jun 2007 18:23:12 +0000 (18:23 +0000)
committerJoshua Colp <jcolp@digium.com>
Wed, 13 Jun 2007 18:23:12 +0000 (18:23 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@69130 65c4cc65-6c06-0410-ace0-fbb531ad65f3

funcs/func_groupcount.c
include/asterisk/app.h
main/app.c
main/cli.c

index 6737af2..a72277a 100644 (file)
@@ -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) {
index 77e77bf..fc763d5 100644 (file)
@@ -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);
index defc008..a818313 100644 (file)
@@ -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(&regexbuf, 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(&regexbuf, gi->group, 0, NULL, 0) && (ast_strlen_zero(category) || !strcasecmp(gi->category, category)))
                        count++;
        }
-       AST_LIST_UNLOCK(&groups);
+       AST_RWLIST_UNLOCK(&groups);
 
        regfree(&regexbuf);
 
@@ -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)
index a3a2532..fa30bf3 100644 (file)
@@ -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) {