]> jfr.im git - irc/freenode/ircd-seven.git/commitdiff
monitor: fix the resource leak properly, unlike the moronic elemental-ircd developers
authorWilliam Pitcock <redacted>
Sun, 11 Oct 2015 23:48:53 +0000 (18:48 -0500)
committerEd Kellett <redacted>
Wed, 28 Dec 2016 20:56:17 +0000 (20:56 +0000)
include/monitor.h
src/monitor.c

index 102fe7e9dd87c127a9b850944c0c70e2cc2b1f27..0d2204b65437f0174fd18b6a2a317df00fc76f26 100644 (file)
@@ -17,10 +17,10 @@ struct monitor
        struct monitor *hnext;
        char name[NICKLEN];
        rb_dlink_list users;
+       rb_dlink_node node;
+       unsigned int hashv;
 };
 
-extern struct monitor *monitorTable[];
-
 #define MONITOR_HASH_BITS 16
 #define MONITOR_HASH_SIZE (1<<MONITOR_HASH_BITS)
 
index 280ef5946107d1e4213cbb83def8bfe4d37c96fd..5038a0957f14ef65a2e905ff7f8ead38504d5edb 100644 (file)
@@ -37,7 +37,7 @@
 #include "hash.h"
 #include "numeric.h"
 
-struct monitor *monitorTable[MONITOR_HASH_SIZE];
+static rb_dlink_list monitorTable[MONITOR_HASH_SIZE];
 static rb_bh *monitor_heap;
 
 void
@@ -56,23 +56,25 @@ struct monitor *
 find_monitor(const char *name, int add)
 {
        struct monitor *monptr;
+       rb_dlink_node *ptr;
 
        unsigned int hashv = hash_monitor_nick(name);
 
-       for(monptr = monitorTable[hashv]; monptr; monptr = monptr->hnext)
+       RB_DLINK_FOREACH(ptr, monitorTable[hashv].head)
        {
+               monptr = ptr->data;
                if(!irccmp(monptr->name, name))
                        return monptr;
+       
        }
 
        if(add)
        {
                monptr = rb_bh_alloc(monitor_heap);
                rb_strlcpy(monptr->name, name, sizeof(monptr->name));
+               monptr->hashv = hashv;
 
-               monptr->hnext = monitorTable[hashv];
-               monitorTable[hashv] = monptr;
-
+               rb_dlinkAdd(monptr, &monptr->node, &monitorTable[hashv]);
                return monptr;
        }
 
@@ -82,6 +84,10 @@ find_monitor(const char *name, int add)
 void
 free_monitor(struct monitor *monptr)
 {
+       if (rb_dlink_list_length(&monptr->users) > 0)
+               return;
+
+       rb_dlinkDelete(&monptr->node, &monitorTable[monptr->hashv]);
        rb_bh_free(monitor_heap, monptr);
 }
 
@@ -139,6 +145,8 @@ clear_monitor(struct Client *client_p)
 
                rb_dlinkFindDestroy(client_p, &monptr->users);
                rb_free_rb_dlink_node(ptr);
+
+               free_monitor(ptr->data);
        }
 
        client_p->localClient->monitor_list.head = client_p->localClient->monitor_list.tail = NULL;