]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Allow MemPool late nitialization
authorAmos Jeffries <squid3@treenet.co.nz>
Sat, 16 Jul 2011 04:00:55 +0000 (16:00 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 16 Jul 2011 04:00:55 +0000 (16:00 +1200)
FQDN had memDataInit() in its component setup, which movedin rev 11499.
The assert is in memCheckInit() and tests that memInit() worked properly.
But if a pool is initialized only when its component is loaded, that
check will fail on several conditions unrelated to the operation of
memory. Seemingly trivial changes to component loading order is one case.

This patch allows modules to initialize/register their own pools on
demand later in the startup process.

* shuffle MEM_DONTFREE which is an existing fixed entry that must not be
  memInitCheck()'d to the end of the MemPool type enum list.

* update memCheckInit() to stop scanning for missing pools at that marker.

* shuffle pool types which are initialized by their components after the
 marker value. Such that no false problem is reported if (a) the
  component is never initialized for that worker, or (b) the component is
  only initialized during the configuration process.

* document this layout significance in the enum list to aid future pool
  additions or moves.

* add asserts to memAllocate() and memFree() to highlight the cases of
  brokenness memCheckInit() was catching. Using assert() instead of if()
  so that optimized builds can avoid the penalty of an extra test on each
  alloc/free.

src/enums.h
src/mem.cc

index 3422976307ca7c19cf83cd4187385a0eedbf2041..f5e2e0dbfdd351129ba89b569707bb4ecec62bf9 100644 (file)
@@ -216,21 +216,23 @@ typedef enum {
     MEM_CLIENT_INFO,
     MEM_LINK_LIST,
     MEM_DLINK_NODE,
-    MEM_DONTFREE,
     MEM_DREAD_CTRL,
     MEM_DWRITE_Q,
-    MEM_FQDNCACHE_ENTRY,
-    MEM_FWD_SERVER,
     MEM_HTTP_HDR_CC,
     MEM_HTTP_HDR_CONTENT_RANGE,
-    MEM_IPCACHE_ENTRY,
     MEM_MD5_DIGEST,
     MEM_NETDBENTRY,
     MEM_NET_DB_NAME,
     MEM_RELIST,
+    // IMPORTANT: leave this here. pools above are initialized early with memInit()
+    MEM_DONTFREE,
+    // following pools are initialized late by their component if needed (or never)
+    MEM_FQDNCACHE_ENTRY,
+    MEM_FWD_SERVER,
 #if !USE_DNSSERVERS
     MEM_IDNS_QUERY,
 #endif
+    MEM_IPCACHE_ENTRY,
     MEM_MAX
 } mem_type;
 
index 9c83e637ffb65cbe3f7843bb24c01a93129de5c0..408052647abbe3a9a09deff1429b6577872467cd 100644 (file)
@@ -202,6 +202,7 @@ memDataInit(mem_type type, const char *name, size_t size, int max_pages_notused,
 void *
 memAllocate(mem_type type)
 {
+    assert(MemPools[type]);
     return MemPools[type]->alloc();
 }
 
@@ -209,6 +210,7 @@ memAllocate(mem_type type)
 void
 memFree(void *p, int type)
 {
+    assert(MemPools[type]);
     MemPools[type]->freeOne(p);
 }
 
@@ -503,15 +505,13 @@ mem_type &operator++ (mem_type &aMem)
 void
 memCheckInit(void)
 {
-    mem_type t;
-
-    for (t = MEM_NONE, ++t; t < MEM_MAX; ++t) {
-        if (MEM_DONTFREE == t)
-            continue;
+    mem_type t = MEM_NONE;
 
+    while (++t < MEM_DONTFREE) {
         /*
          * If you hit this assertion, then you forgot to add a
          * memDataInit() line for type 't'.
+         * Or placed the pool type in the wrong section of the enum list.
          */
         assert(MemPools[t]);
     }