]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
automerge commit
authorAutomerge script <automerge@asterisk.org>
Fri, 26 May 2006 18:06:03 +0000 (18:06 +0000)
committerAutomerge script <automerge@asterisk.org>
Fri, 26 May 2006 18:06:03 +0000 (18:06 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@30577 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_queue.c

index 58a85813c83ed066b192ecc745970625fb74ddd9..5e41b990ded87a1066a078d5f5da43eca09b0f1e 100644 (file)
@@ -303,6 +303,13 @@ struct member {
        struct member *next;            /*!< Next member */
 };
 
+struct ast_member_interfaces {
+       char interface[80];
+       AST_LIST_ENTRY(ast_member_interfaces) list;    /*!< Next call queue */
+};
+
+static AST_LIST_HEAD_STATIC(interfaces, ast_member_interfaces);
+
 /* values used in multi-bit flags in ast_call_queue */
 #define QUEUE_EMPTY_NORMAL 1
 #define QUEUE_EMPTY_STRICT 2
@@ -458,6 +465,7 @@ static void *changethread(void *data)
        struct ast_call_queue *q;
        struct statechange *sc = data;
        struct member *cur;
+       struct ast_member_interfaces *curint;
        char *loc;
        char *technology;
 
@@ -470,36 +478,50 @@ static void *changethread(void *data)
                free(sc);
                return NULL;
        }
-       if (option_debug)
-               ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
-       ast_mutex_lock(&qlock);
-       for (q = queues; q; q = q->next) {
-               ast_mutex_lock(&q->lock);
-               cur = q->members;
-               while(cur) {
-                       if (!strcasecmp(sc->dev, cur->interface)) {
-                               if (cur->status != sc->state) {
-                                       cur->status = sc->state;
-                                       if (!q->maskmemberstatus) {
-                                               manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
-                                                       "Queue: %s\r\n"
-                                                       "Location: %s\r\n"
-                                                       "Membership: %s\r\n"
-                                                       "Penalty: %d\r\n"
-                                                       "CallsTaken: %d\r\n"
-                                                       "LastCall: %d\r\n"
-                                                       "Status: %d\r\n"
-                                                       "Paused: %d\r\n",
-                                               q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
-                                               cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
+
+       AST_LIST_LOCK(&interfaces);
+       AST_LIST_TRAVERSE(&interfaces, curint, list) {
+               if (!strcasecmp(curint->interface, sc->dev))
+                       break;
+       }
+       AST_LIST_UNLOCK(&interfaces);
+       
+       if (curint) {
+
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
+               ast_mutex_lock(&qlock);
+               for (q = queues; q; q = q->next) {
+                       ast_mutex_lock(&q->lock);
+                       cur = q->members;
+                       while(cur) {
+                               if (!strcasecmp(sc->dev, cur->interface)) {
+                                       if (cur->status != sc->state) {
+                                               cur->status = sc->state;
+                                               if (!q->maskmemberstatus) {
+                                                       manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
+                                                               "Queue: %s\r\n"
+                                                               "Location: %s\r\n"
+                                                               "Membership: %s\r\n"
+                                                               "Penalty: %d\r\n"
+                                                               "CallsTaken: %d\r\n"
+                                                               "LastCall: %d\r\n"
+                                                               "Status: %d\r\n"
+                                                               "Paused: %d\r\n",
+                                                       q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
+                                                       cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
+                                               }
                                        }
                                }
+                               cur = cur->next;
                        }
-                       cur = cur->next;
+                       ast_mutex_unlock(&q->lock);
                }
-               ast_mutex_unlock(&q->lock);
-       }
-       ast_mutex_unlock(&qlock);
+               ast_mutex_unlock(&qlock);
+       } else {
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
+        }
        free(sc);
        return NULL;
 }
@@ -596,6 +618,89 @@ static void clear_queue(struct ast_call_queue *q)
        q->wrapuptime = 0;
 }
 
+static int add_to_interfaces(char *interface) 
+{
+       struct ast_member_interfaces *curint, *newint;
+
+       AST_LIST_LOCK(&interfaces);
+       AST_LIST_TRAVERSE(&interfaces, curint, list) {
+               if (!strcasecmp(curint->interface, interface))
+                       break; 
+       }
+
+       if (!curint) {
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
+
+               if ((newint = malloc(sizeof(*newint)))) {
+                       memset(newint, 0, sizeof(*newint));
+                       ast_copy_string(newint->interface, interface, sizeof(newint->interface));
+                       AST_LIST_INSERT_HEAD(&interfaces, newint, list);
+               }
+       }
+       AST_LIST_UNLOCK(&interfaces);
+
+ return 0;
+}
+
+static int interface_exists_global(char *interface)
+{
+       struct ast_call_queue *q;
+       struct member *mem;
+       int ret = 0;
+
+       ast_mutex_lock(&qlock);
+       for (q = queues; q && !ret; q = q->next) {
+               ast_mutex_lock(&q->lock);
+               mem = q->members;
+               while(mem) {
+                       if (!strcasecmp(interface, mem->interface)) {
+                               ret = 1;
+                               break;
+                       }
+               }
+               ast_mutex_unlock(&q->lock);
+       }
+       ast_mutex_unlock(&qlock);
+
+       return ret;
+}
+
+
+static int remove_from_interfaces(char *interface)
+{
+       struct ast_member_interfaces *curint;
+
+       AST_LIST_LOCK(&interfaces);
+       AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
+               if (!strcasecmp(curint->interface, interface) && !interface_exists_global(interface)) {
+                       if (option_debug)
+                               ast_log(LOG_DEBUG, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
+                       AST_LIST_REMOVE_CURRENT(&interfaces, list);
+                       free(curint);
+               }
+       }
+       AST_LIST_TRAVERSE_SAFE_END;
+       AST_LIST_UNLOCK(&interfaces);
+
+       return 0;
+}
+
+static void clear_and_free_interfaces(void)
+{
+       struct ast_member_interfaces *curint;
+
+       AST_LIST_LOCK(&interfaces);
+       AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
+               AST_LIST_REMOVE_CURRENT(&interfaces, list);
+               free(curint);
+       }
+       AST_LIST_TRAVERSE_SAFE_END;
+       AST_LIST_UNLOCK(&interfaces);
+
+       return;
+}
+
 /*! \brief Configure a queue parameter.
 \par
    For error reporting, line number is passed for .conf static configuration.
@@ -746,6 +851,7 @@ static void rt_handle_member_record(struct ast_call_queue *q, char *interface, c
                m = create_queue_member(interface, penalty, 0);
                if (m) {
                        m->dead = 0;
+                       add_to_interfaces(interface);
                        if (prev_m) {
                                prev_m->next = m;
                        } else {
@@ -770,6 +876,7 @@ static void free_members(struct ast_call_queue *q, int all)
                                prev->next = next;
                        else
                                q->members = next;
+                       remove_from_interfaces(curm->interface);
                        free(curm);
                } else 
                        prev = curm;
@@ -917,6 +1024,7 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
                        } else {
                                q->members = next_m;
                        }
+                       remove_from_interfaces(m->interface);
                        free(m);
                } else {
                        prev_m = m;
@@ -1033,9 +1141,9 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
                              qe->chan->cid.cid_num ? qe->chan->cid.cid_num : "unknown",
                              qe->chan->cid.cid_name ? qe->chan->cid.cid_name : "unknown",
                              q->name, qe->pos, q->count );
-#if 0
-ast_log(LOG_NOTICE, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
-#endif
+
+               if (option_debug)
+                       ast_log(LOG_DEBUG, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
        }
        ast_mutex_unlock(&q->lock);
        ast_mutex_unlock(&qlock);
@@ -2421,6 +2529,8 @@ static int remove_from_queue(char *queuename, char *interface)
                }
                ast_mutex_unlock(&q->lock);
        }
+       if (res == RES_OKAY)
+               remove_from_interfaces(interface);
        ast_mutex_unlock(&qlock);
        return res;
 }
@@ -2440,6 +2550,9 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause
        if (q) {
                ast_mutex_lock(&q->lock);
                if (interface_exists(q, interface) == NULL) {
+
+                       add_to_interfaces(interface);
+
                        new_member = create_queue_member(interface, penalty, paused);
 
                        if (new_member != NULL) {
@@ -3251,6 +3364,8 @@ static void reload_queues(void)
                                                        }
                                                        free(cur);
                                                } else {
+                                                       /* Add them to the master int list if necessary */
+                                                       add_to_interfaces(interface);
                                                        newm->next = q->members;
                                                        q->members = newm;
                                                }
@@ -3275,6 +3390,7 @@ static void reload_queues(void)
                                                        q->members = cur->next;
                                                        newm = cur;
                                                }
+                                               remove_from_interfaces(cur->interface);
                                        }
                                }
                                if (!new) 
@@ -3827,6 +3943,7 @@ int unload_module(void)
 {
        int res;
 
+       clear_and_free_interfaces();
        res = ast_cli_unregister(&cli_show_queue);
        res |= ast_cli_unregister(&cli_show_queues);
        res |= ast_cli_unregister(&cli_add_queue_member);