=== modified file 'src/mem.cc'
--- src/mem.cc	2011-03-30 16:50:18 +0000
+++ src/mem.cc	2011-04-05 06:42:54 +0000
@@ -44,61 +44,67 @@
 #include "SquidTime.h"
 
 #if HAVE_IOMANIP
 #include <iomanip>
 #endif
 #if HAVE_OSTREAM
 #include <ostream>
 #endif
 
 /* module globals */
 const size_t squidSystemPageSize=getpagesize();
 
 /* local prototypes */
 static void memStringStats(std::ostream &);
 
 /* module locals */
 static MemAllocator *MemPools[MEM_MAX];
 static double xm_time = 0;
 static double xm_deltat = 0;
 
+/* all pools are ready to be used */
+static bool MemIsInitialized=false;
+
 /* string pools */
 #define mem_str_pool_count 3
 
 static const struct {
     const char *name;
     size_t obj_size;
 }
 
 StrPoolsAttrs[mem_str_pool_count] = {
 
     {
         "Short Strings", MemAllocator::RoundedSize(36),
     },				/* to fit rfc1123 and similar */
     {
         "Medium Strings", MemAllocator::RoundedSize(128),
     },				/* to fit most urls */
     {
         "Long Strings", MemAllocator::RoundedSize(512)
     }				/* other */
 };
 
+// must be at least one byte bigger than the biggest string size
+static const size_t SizeOfStringBeforePoolsAreInitialized = 513;
+
 static struct {
     MemAllocator *pool;
 }
 
 StrPools[mem_str_pool_count];
 static MemMeter StrCountMeter;
 static MemMeter StrVolumeMeter;
 
 static MemMeter HugeBufCountMeter;
 static MemMeter HugeBufVolumeMeter;
 
 /* local routines */
 
 static void
 memStringStats(std::ostream &stream)
 {
     int i;
     int pooled_count = 0;
     size_t pooled_volume = 0;
     /* heading */
@@ -173,90 +179,97 @@
     assert(MemPools[type] == NULL);
     MemPools[type] = memPoolCreate(name, size);
     MemPools[type]->zeroOnPush(zeroOnPush);
 }
 
 
 /* find appropriate pool and use it (pools always init buffer with 0s) */
 void *
 memAllocate(mem_type type)
 {
     return MemPools[type]->alloc();
 }
 
 /* give memory back to the pool */
 void
 memFree(void *p, int type)
 {
     MemPools[type]->freeOne(p);
 }
 
-/* allocate a variable size buffer using best-fit pool */
 void *
 memAllocString(size_t net_size, size_t * gross_size)
 {
-    int i;
     MemAllocator *pool = NULL;
     assert(gross_size);
 
+    // if pools are not yet ready, make sure that
+    // the requested size is not poolable
+    if (!MemIsInitialized && net_size < SizeOfStringBeforePoolsAreInitialized)
+    	net_size=SizeOfStringBeforePoolsAreInitialized;
+
+    unsigned int i=0;
     for (i = 0; i < mem_str_pool_count; ++i) {
         if (net_size <= StrPoolsAttrs[i].obj_size) {
             pool = StrPools[i].pool;
             break;
         }
     }
 
     *gross_size = pool ? StrPoolsAttrs[i].obj_size : net_size;
     assert(*gross_size >= net_size);
+    // may forget [de]allocations until MemIsInitialized
     memMeterInc(StrCountMeter);
     memMeterAdd(StrVolumeMeter, *gross_size);
     return pool ? pool->alloc() : xcalloc(1, net_size);
 }
 
 extern size_t memStringCount();
 size_t
 memStringCount()
 {
     size_t result = 0;
 
     for (int counter = 0; counter < mem_str_pool_count; ++counter)
         result += memPoolInUseCount(StrPools[counter].pool);
 
     return result;
 }
 
 /* free buffer allocated with memAllocString() */
 void
 memFreeString(size_t size, void *buf)
 {
-    int i;
     MemAllocator *pool = NULL;
-    assert(size && buf);
+    assert(buf);
 
-    for (i = 0; i < mem_str_pool_count; ++i) {
-        if (size <= StrPoolsAttrs[i].obj_size) {
-            assert(size == StrPoolsAttrs[i].obj_size);
-            pool = StrPools[i].pool;
-            break;
+    if (MemIsInitialized) {
+        for (unsigned int i = 0; i < mem_str_pool_count; ++i) {
+            if (size <= StrPoolsAttrs[i].obj_size) {
+                assert(size == StrPoolsAttrs[i].obj_size);
+                pool = StrPools[i].pool;
+                break;
+            }
         }
     }
 
+    // may forget [de]allocations until MemIsInitialized
     memMeterDec(StrCountMeter);
     memMeterDel(StrVolumeMeter, size);
     pool ? pool->freeOne(buf) : xfree(buf);
 }
 
 /* Find the best fit MEM_X_BUF type */
 static mem_type
 memFindBufSizeType(size_t net_size, size_t * gross_size)
 {
     mem_type type;
     size_t size;
 
     if (net_size <= 2 * 1024) {
         type = MEM_2K_BUF;
         size = 2 * 1024;
     } else if (net_size <= 4 * 1024) {
         type = MEM_4K_BUF;
         size = 4 * 1024;
     } else if (net_size <= 8 * 1024) {
         type = MEM_8K_BUF;
@@ -421,40 +434,41 @@
     memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
     memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
     memDataInit(MEM_HTTP_HDR_CC, "HttpHdrCc", sizeof(HttpHdrCc), 0);
     memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0);
     memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
     memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
     memDataInit(MEM_RELIST, "relist", sizeof(relist), 0);
     memDataInit(MEM_CLIENT_INFO, "ClientInfo", sizeof(ClientInfo), 0);
     memDataInit(MEM_MD5_DIGEST, "MD5 digest", SQUID_MD5_DIGEST_LENGTH, 0);
     MemPools[MEM_MD5_DIGEST]->setChunkSize(512 * 1024);
 
     /** Lastly init the string pools. */
     for (i = 0; i < mem_str_pool_count; ++i) {
         StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
         StrPools[i].pool->zeroOnPush(false);
 
         if (StrPools[i].pool->objectSize() != StrPoolsAttrs[i].obj_size)
             debugs(13, 1, "Notice: " << StrPoolsAttrs[i].name << " is " << StrPools[i].pool->objectSize() << " bytes instead of requested " << StrPoolsAttrs[i].obj_size << " bytes");
     }
 
+    MemIsInitialized=true;
     /** \par
      * finally register with the cache manager */
     RegisterWithCacheManager();
 }
 
 void
 Mem::Report()
 {
     debugs(13, 3, "Memory pools are '" <<
            (Config.onoff.mem_pools ? "on" : "off")  << "'; limit: " <<
            std::setprecision(3) << toMB(MemPools::GetInstance().idleLimit()) <<
            " MB");
 }
 
 void
 Mem::RegisterWithCacheManager(void)
 {
     Mgr::RegisterAction("mem", "Memory Utilization", Mem::Stats, 0, 1);
 }
 

