--- /home/users/striker/apr_pools.c	Sat Aug 25 15:34:31 2001
+++ srclib/apr/memory/unix/apr_pools.c	Sun Aug 26 16:51:42 2001
@@ -133,13 +133,21 @@
 typedef struct cleanup_t cleanup_t;
 typedef struct allocator_t allocator_t;
 typedef struct node_t node_t;
+typedef struct block_t block_t;
+
+struct block_t {
+    node_t      *node;
+};
 
 struct node_t {
     node_t      *next;
+    node_t     **ref;
+    
     apr_uint32_t index;
 
     char        *first_avail;
     char        *endp;
+    apr_uint32_t count;
 };
 
 struct allocator_t {
@@ -166,6 +174,7 @@
 #endif
 };
 
+#define SIZEOF_BLOCK_T      ALIGN_DEFAULT(sizeof(block_t))
 #define SIZEOF_NODE_T       ALIGN_DEFAULT(sizeof(node_t))
 #define SIZEOF_ALLOCATOR_T  ALIGN_DEFAULT(sizeof(allocator_t))
 #define SIZEOF_POOL_T       ALIGN_DEFAULT(sizeof(apr_pool_t))
@@ -292,17 +301,20 @@
 APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size)
 {
     node_t *active, *node;
-    void *mem;
+    block_t *block;
     char *endp;
 
-    size = ALIGN_DEFAULT(size);
-    active = pool->mactive;
+    size = ALIGN_DEFAULT(size) + SIZEOF_BLOCK_T;
 
+    active = pool->mactive;
     endp = active->first_avail + size;
     if (endp < active->endp) {
-        mem = active->first_avail;
+        block = (block_t *)active->first_avail;
         active->first_avail = endp;
-        return mem;
+        active->count++;
+        block->node = active;
+        
+        return (char *)block + SIZEOF_BLOCK_T;
     }
 
     /*
@@ -320,26 +332,34 @@
     }
 
     active->next = pool->mactive = node; 
+    node->ref = &active->next;
 
-    mem = node->first_avail;
+    block = (block_t *)node->first_avail;
     node->first_avail += size;
+    node->count = 1;
+    block->node = node;
 
-    return mem;
+    return (char *)block + SIZEOF_BLOCK_T;
 }
 
 APR_DECLARE(void *) apr_pcalloc(apr_pool_t *pool, apr_size_t size)
 {
     node_t *active, *node;
+    block_t *block;
     void *mem;
     char *endp;
 
-    size = ALIGN_DEFAULT(size);
-    active = pool->mactive;
+    size = ALIGN_DEFAULT(size) + SIZEOF_BLOCK_T;
 
+    active = pool->mactive;
     endp = active->first_avail + size;
     if (endp < active->endp) {
-        mem = active->first_avail;
+        block = (block_t *)active->first_avail;
         active->first_avail = endp;
+        active->count++;
+        block->node = active;
+        mem = (char *)block + SIZEOF_BLOCK_T;
+        
         memset(mem, 0, size);
         return mem;
     }
@@ -359,14 +379,41 @@
     }
 
     active->next = pool->mactive = node; 
+    node->ref = &active->next;
 
-    mem = node->first_avail;
+    block = (block_t *)node->first_avail;
     node->first_avail += size;
+    node->count = 1;
+    block->node = node;
+    mem = (char *)block + SIZEOF_BLOCK_T;
+    
     memset(mem, 0, size);
-
     return mem;
 }
 
+APR_DECLARE(void) apr_pfree(apr_pool_t *pool, void *mem)
+{
+    block_t *block;
+    node_t *node;
+    
+    if (!mem)
+        return;
+
+    block = (block_t *)((char *)mem - SIZEOF_BLOCK_T);
+    node = block->node;
+
+    if (node->count > 1 || pool->mactive == node) {
+        node->count--;
+        return;
+    }
+
+    *node->ref = node->next;
+    node->next->ref = node->ref;
+
+    node->next = NULL;
+    node_free(pool->allocator, node);
+}
+
 /*
  * Pool management
  */
@@ -399,8 +446,10 @@
     active = pool->mactive;
     active->first_avail = (char *)active + SIZEOF_NODE_T;
 
-    if (active == pool->self)
+    if (active == pool->self) {
+        active->count = 1;
         return;
+    }
     
     /*
      * Find the block attached to the pool structure.
@@ -408,6 +457,7 @@
     active = pool->mactive = pool->self; 
     node_free(pool->allocator, active->next);
     active->next = NULL;
+    active->count = 1;
 }
 
 APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool)
@@ -542,6 +592,7 @@
         node->first_avail = (char *)node + SIZEOF_NODE_T;
         node->endp = (char *)pool + MIN_ALLOC;
         node->next = NULL;
+        node->count = 1;
         pool->allocator = allocator;
         pool->mactive = pool->self = node;
         pool->abort_fn = abort_fn;
@@ -562,7 +613,6 @@
             }
         }
 
-
         if ((pool->parent = parent) != NULL) {
             lock = parent->allocator->lock;
             
@@ -603,6 +653,7 @@
     node->endp = endp;
     node->index = index;
     node->next = NULL;
+    node->count = 1;
     pool->mactive = pool->self = node;
     pool->abort_fn = abort_fn;
     pool->child = NULL;
@@ -983,7 +1034,7 @@
 
     if (ps.free)
         node_free(ps.allocator, ps.free);
-
+    
     return strp;
 }
 
