Remove some ref leaks and a return without unlock.
authorGregory Nietsky <gregory@distrotech.co.za>
Sun, 23 Oct 2011 14:35:26 +0000 (14:35 +0000)
committerGregory Nietsky <gregory@distrotech.co.za>
Sun, 23 Oct 2011 14:35:26 +0000 (14:35 +0000)
There some resource leaks introduced in asterisk 10
make sure that locks are not held on return and we
release ref's held.
........

Merged revisions 341972 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@341973 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_queue.c

index fee840c..ce886df 100644 (file)
@@ -3498,8 +3498,10 @@ static void rna(int rnatime, struct queue_ent *qe, char *interface, char *member
                                time_t idletime = time(&idletime)-mem->lastcall;
                                if ((mem->lastcall != 0) && (qe->parent->autopausedelay > idletime)) {
                                        ao2_unlock(qe->parent);
+                                       ao2_ref(mem, -1);
                                        return;
                                }
+                               ao2_ref(mem, -1);
                        }
                        ao2_unlock(qe->parent);
                }
@@ -5759,7 +5761,7 @@ static int rqm_exec(struct ast_channel *chan, const char *data)
 
        switch (remove_from_queue(args.queuename, args.interface)) {
        case RES_OKAY:
-               if (!mem || ast_strlen_zero(mem->membername) || !log_membername_as_agent) {
+               if (!mem || ast_strlen_zero(mem->membername)) {
                        ast_queue_log(args.queuename, chan->uniqueid, args.interface, "REMOVEMEMBER", "%s", "");
                } else {
                        ast_queue_log(args.queuename, chan->uniqueid, mem->membername, "REMOVEMEMBER", "%s", "");
@@ -5785,6 +5787,10 @@ static int rqm_exec(struct ast_channel *chan, const char *data)
                break;
        }
 
+       if (mem) {
+               ao2_ref(mem, -1);
+       }
+
        return res;
 }
 
@@ -6360,12 +6366,15 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
                } else if (!strcasecmp(args.option, "penalty") && !ast_strlen_zero(args.interface) &&
                           ((m = interface_exists(q, args.interface)))) {
                        count = m->penalty;
+                       ao2_ref(m, -1);
                } else if (!strcasecmp(args.option, "paused") && !ast_strlen_zero(args.interface) &&
                           ((m = interface_exists(q, args.interface)))) {
                        count = m->paused;
+                       ao2_ref(m, -1);
                } else if (!strcasecmp(args.option, "ignorebusy") && !ast_strlen_zero(args.interface) &&
                           ((m = interface_exists(q, args.interface)))) {
                        count = m->ignorebusy;
+                       ao2_ref(m, -1);
                }
                ao2_unlock(q);
                queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER()");
@@ -6435,13 +6444,20 @@ static int queue_function_mem_write(struct ast_channel *chan, const char *cmd, c
                                }
                        } else {
                                ast_log(LOG_ERROR, "Invalid option, only penalty , paused or ignorebusy are valid\n");
+                               ao2_ref(m, -1);
+                               ao2_unlock(q);
+                               ao2_ref(q, -1);
                                return -1;
                        }
+                       ao2_ref(m, -1);
                } else {
-                       ast_log(LOG_ERROR, "Invalid interface or queue\n");
+                       ao2_unlock(q);
+                       ao2_ref(q, -1);
+                       ast_log(LOG_ERROR, "Invalid interface for queue\n");
                        return -1;
                }
                ao2_unlock(q);
+               ao2_ref(q, -1);
         } else {
                ast_log(LOG_ERROR, "Invalid queue\n");
                return -1;
@@ -7619,7 +7635,7 @@ static int manager_remove_queue_member(struct mansession *s, const struct messag
 
        switch (remove_from_queue(queuename, interface)) {
        case RES_OKAY:
-               if (!mem || ast_strlen_zero(mem->membername) || !log_membername_as_agent) {
+               if (!mem || ast_strlen_zero(mem->membername)) {
                        ast_queue_log(queuename, "MANAGER", interface, "REMOVEMEMBER", "%s", "");
                } else {
                        ast_queue_log(queuename, "MANAGER", mem->membername, "REMOVEMEMBER", "%s", "");
@@ -7640,6 +7656,10 @@ static int manager_remove_queue_member(struct mansession *s, const struct messag
                break;
        }
 
+       if (mem) {
+               ao2_ref(mem, -1);
+       }
+
        return 0;
 }
 
@@ -7939,17 +7959,19 @@ static char *handle_queue_remove_member(struct ast_cli_entry *e, int cmd, struct
        queuename = a->argv[5];
        interface = a->argv[3];
 
-       if (log_membername_as_agent) {
-               mem = find_member_by_queuename_and_interface(queuename, interface);
-       }
-
        switch (remove_from_queue(queuename, interface)) {
        case RES_OKAY:
-               if (!mem || ast_strlen_zero(mem->membername) || !log_membername_as_agent) {
+               if (log_membername_as_agent) {
+                       mem = find_member_by_queuename_and_interface(queuename, interface);
+               }
+               if (!mem || ast_strlen_zero(mem->membername)) {
                        ast_queue_log(queuename, "CLI", interface, "REMOVEMEMBER", "%s", "");
                } else {
                        ast_queue_log(queuename, "CLI", mem->membername, "REMOVEMEMBER", "%s", "");
                }
+               if (mem) {
+                       ao2_ref(mem, -1);
+               }
                ast_cli(a->fd, "Removed interface %s from queue '%s'\n", interface, queuename);
                return CLI_SUCCESS;
        case RES_EXISTS: