Return-Path: Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 39921 invoked by uid 500); 5 Mar 2002 08:58:57 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 39908 invoked from network); 5 Mar 2002 08:58:56 -0000 From: "Sander Striker" To: , Subject: [PATCH] First cut at factoring out the pools allocator Date: Tue, 5 Mar 2002 10:02:55 +0100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0364_01C1C42C.EBBBE7D0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Importance: Normal X-Rcpt-To: X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. ------=_NextPart_000_0364_01C1C42C.EBBBE7D0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi, Below a patch to apr and a patch to httpd to factor out the allocator from pools. It is only the first cut, so crucial details like documentation are missing. I'd like some feedback on the general idea though. Hopefully this helps when implementing the bucket allocator. Sander Two patches inline, one new apr file attached which should go into include/. The apr stuff. Index: include/apr_pools.h =================================================================== RCS file: /home/cvs/apr/include/apr_pools.h,v retrieving revision 1.78 diff -u -r1.78 apr_pools.h --- include/apr_pools.h 9 Feb 2002 14:08:39 -0000 1.78 +++ include/apr_pools.h 2 Mar 2002 17:46:26 -0000 @@ -86,6 +86,11 @@ #define APR_WANT_MEMFUNC #include "apr_want.h" +/** The fundamental pool type */ +typedef struct apr_pool_t apr_pool_t; + +#include "apr_allocator.h" + /** * Pool debug levels * @@ -127,14 +132,12 @@ #else #define APR_POOL_DEBUG 0 #endif - + #define APR_POOL_STRINGIZE(x) APR_POOL__STRINGIZE(x) #define APR_POOL__STRINGIZE(x) #x #define APR_POOL__FILE_LINE__ __FILE__ ":" APR_POOL_STRINGIZE(__LINE__) - - -/** The fundamental pool type */ -typedef struct apr_pool_t apr_pool_t; + + /** A function that is called when allocation fails. */ typedef int (*apr_abortfunc_t)(int retcode); @@ -193,7 +196,7 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, - apr_uint32_t flags); + apr_allocator_t *allocator); /** * Debug version of apr_pool_create_ex. @@ -214,7 +217,7 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, - apr_uint32_t flags, + apr_allocator_t *allocator, const char *file_line); #if APR_POOL_DEBUG Index: memory/unix/apr_pools.c =================================================================== RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v retrieving revision 1.155 diff -u -r1.155 apr_pools.c --- memory/unix/apr_pools.c 2 Mar 2002 09:26:07 -0000 1.155 +++ memory/unix/apr_pools.c 2 Mar 2002 17:46:31 -0000 @@ -59,6 +59,7 @@ #include "apr_strings.h" #include "apr_general.h" #include "apr_pools.h" +#include "apr_allocator.h" #include "apr_lib.h" #include "apr_thread_mutex.h" #include "apr_hash.h" @@ -76,17 +77,17 @@ /* - * Debug level + * XXX: Memory node struct, move to private header file */ +struct apr_memnode_t { + apr_memnode_t *next; + apr_uint32_t index; + char *first_avail; + char *endp; +}; -#define APR_POOL_DEBUG_GENERAL 0x01 -#define APR_POOL_DEBUG_VERBOSE 0x02 -#define APR_POOL_DEBUG_LIFETIME 0x04 -#define APR_POOL_DEBUG_OWNER 0x08 -#define APR_POOL_DEBUG_VERBOSE_ALLOC 0x10 +#define SIZEOF_MEMNODE_T APR_ALIGN_DEFAULT(sizeof(apr_memnode_t)) -#define APR_POOL_DEBUG_VERBOSE_ALL (APR_POOL_DEBUG_VERBOSE \ - | APR_POOL_DEBUG_VERBOSE_ALLOC) /* * Magic numbers @@ -100,199 +101,94 @@ /* - * Structures + * Allocator */ - -typedef struct cleanup_t cleanup_t; - -#if !APR_POOL_DEBUG -typedef struct allocator_t allocator_t; -typedef struct node_t node_t; - -struct node_t { - node_t *next; - apr_uint32_t index; - char *first_avail; - char *endp; -}; - -struct allocator_t { +struct apr_allocator_t { apr_uint32_t max_index; #if APR_HAS_THREADS apr_thread_mutex_t *mutex; #endif /* APR_HAS_THREADS */ apr_pool_t *owner; - node_t *free[MAX_INDEX]; -}; - -#define SIZEOF_NODE_T APR_ALIGN_DEFAULT(sizeof(node_t)) -#define SIZEOF_ALLOCATOR_T APR_ALIGN_DEFAULT(sizeof(allocator_t)) - -#else /* APR_POOL_DEBUG */ - -typedef struct debug_node_t debug_node_t; - -struct debug_node_t { - debug_node_t *next; - apr_uint32_t index; - void *beginp[64]; - void *endp[64]; -}; - -#define SIZEOF_DEBUG_NODE_T APR_ALIGN_DEFAULT(sizeof(debug_node_t)) - -#endif /* APR_POOL_DEBUG */ - -/* The ref field in the apr_pool_t struct holds a - * pointer to the pointer referencing this pool. - * It is used for parent, child, sibling management. - * Look at apr_pool_create_ex() and apr_pool_destroy() - * to see how it is used. - */ -struct apr_pool_t { - apr_pool_t *parent; - apr_pool_t *child; - apr_pool_t *sibling; - apr_pool_t **ref; - cleanup_t *cleanups; - struct process_chain *subprocesses; - apr_abortfunc_t abort_fn; - apr_hash_t *user_data; - const char *tag; - -#if !APR_POOL_DEBUG - allocator_t *allocator; - node_t *active; - node_t *self; /* The node containing the pool itself */ - char *self_first_avail; - -#else /* APR_POOL_DEBUG */ - debug_node_t *nodes; - const char *file_line; - apr_uint32_t creation_flags; - unsigned int stat_alloc; - unsigned int stat_total_alloc; - unsigned int stat_clear; -#if APR_HAS_THREADS - apr_os_thread_t owner; - apr_thread_mutex_t *mutex; -#endif /* APR_HAS_THREADS */ -#endif /* APR_POOL_DEBUG */ -#ifdef NETWARE - apr_os_proc_t owner_proc; -#endif /* defined(NETWARE) */ -}; - -#define SIZEOF_POOL_T APR_ALIGN_DEFAULT(sizeof(apr_pool_t)) - - -/* - * Variables - */ - -static apr_byte_t apr_pools_initialized = 0; -static apr_pool_t *global_pool = NULL; - -#if !APR_POOL_DEBUG -static allocator_t global_allocator = { - 0, /* max_index */ -#if APR_HAS_THREADS - NULL, /* mutex */ -#endif /* APR_HAS_THREADS */ - NULL, /* owner */ - { NULL } /* free[0] */ + apr_memnode_t *free[MAX_INDEX]; }; -#endif /* !APR_POOL_DEBUG */ - -#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) -static apr_file_t *file_stderr = NULL; -#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */ - -/* - * Local functions - */ -static void run_cleanups(cleanup_t *c); -static void run_child_cleanups(cleanup_t *c); -static void free_proc_chain(struct process_chain *procs); +#define SIZEOF_ALLOCATOR_T APR_ALIGN_DEFAULT(sizeof(apr_allocator_t)) -#if !APR_POOL_DEBUG /* - * Initialization + * Allocator */ -APR_DECLARE(apr_status_t) apr_pool_initialize(void) +APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator) { - apr_status_t rv; + apr_allocator_t *new_allocator; - if (apr_pools_initialized++) - return APR_SUCCESS; + *allocator = NULL; - memset(&global_allocator, 0, sizeof(global_allocator)); + if ((new_allocator = malloc(SIZEOF_ALLOCATOR_T)) == NULL) + return APR_ENOMEM; - if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL, APR_POOL_FDEFAULT)) != APR_SUCCESS) { - return rv; - } + memset(new_allocator, 0, SIZEOF_ALLOCATOR_T); -#if APR_HAS_THREADS - if ((rv = apr_thread_mutex_create(&global_allocator.mutex, - APR_THREAD_MUTEX_DEFAULT, global_pool)) != APR_SUCCESS) { - return rv; - } -#endif /* APR_HAS_THREADS */ - - global_allocator.owner = global_pool; - apr_pools_initialized = 1; + *allocator = new_allocator; return APR_SUCCESS; } -APR_DECLARE(void) apr_pool_terminate(void) +APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator) { - if (!apr_pools_initialized) - return; + apr_uint32_t index; + apr_memnode_t *node, **ref; - apr_pools_initialized = 0; + for (index = 0; index < MAX_INDEX; index++) { + ref = &allocator->free[index]; + while ((node = *ref) != NULL) { + *ref = node->next; + free(node); + } + } - apr_pool_destroy(global_pool); /* This will also destroy the mutex */ - global_pool = NULL; + free(allocator); +} - memset(&global_allocator, 0, sizeof(global_allocator)); +#if APR_HAS_THREADS +APR_INLINE +APR_DECLARE(void) apr_allocator_set_mutex(apr_allocator_t *allocator, + apr_thread_mutex_t *mutex) +{ + allocator->mutex = mutex; } -#ifdef NETWARE -void netware_pool_proc_cleanup () +APR_INLINE +APR_DECLARE(apr_thread_mutex_t *) apr_allocator_get_mutex( + apr_allocator_t *allocator) { - apr_pool_t *pool = global_pool->child; - apr_os_proc_t owner_proc = (apr_os_proc_t)getnlmhandle(); + return allocator->mutex; +} +#endif /* APR_HAS_THREADS */ - while (pool) { - if (pool->owner_proc == owner_proc) { - apr_pool_destroy (pool); - pool = global_pool->child; - } - else { - pool = pool->sibling; - } - } - return; +APR_DECLARE(void) apr_allocator_set_owner(apr_allocator_t *allocator, + apr_pool_t *pool) +{ + allocator->owner = pool; } -#endif /* defined(NETWARE) */ -/* - * Memory allocation - */ +APR_DECLARE(apr_pool_t *) apr_allocator_get_owner(apr_allocator_t *allocator) +{ + return allocator->owner; +} -static APR_INLINE node_t *node_malloc(allocator_t *allocator, apr_size_t size) +APR_INLINE +APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator, + apr_size_t size) { - node_t *node, **ref; + apr_memnode_t *node, **ref; apr_uint32_t i, index, max_index; /* Round up the block size to the next boundary, but always * allocate at least a certain size (MIN_ALLOC). */ - size = APR_ALIGN(size + SIZEOF_NODE_T, BOUNDARY_SIZE); + size = APR_ALIGN(size + SIZEOF_MEMNODE_T, BOUNDARY_SIZE); if (size < MIN_ALLOC) size = MIN_ALLOC; @@ -350,7 +246,7 @@ #endif /* APR_HAS_THREADS */ node->next = NULL; - node->first_avail = (char *)node + SIZEOF_NODE_T; + node->first_avail = (char *)node + SIZEOF_MEMNODE_T; return node; } @@ -386,7 +282,7 @@ #endif /* APR_HAS_THREADS */ node->next = NULL; - node->first_avail = (char *)node + SIZEOF_NODE_T; + node->first_avail = (char *)node + SIZEOF_MEMNODE_T; return node; } @@ -405,15 +301,16 @@ node->next = NULL; node->index = index; - node->first_avail = (char *)node + SIZEOF_NODE_T; + node->first_avail = (char *)node + SIZEOF_MEMNODE_T; node->endp = (char *)node + size; return node; } -static APR_INLINE void node_free(allocator_t *allocator, node_t *node) +APR_INLINE +APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator, apr_memnode_t *node) { - node_t *next; + apr_memnode_t *next; apr_uint32_t index, max_index; #if APR_HAS_THREADS @@ -457,9 +354,192 @@ #endif /* APR_HAS_THREADS */ } + +/* + * Debug level + */ + +#define APR_POOL_DEBUG_GENERAL 0x01 +#define APR_POOL_DEBUG_VERBOSE 0x02 +#define APR_POOL_DEBUG_LIFETIME 0x04 +#define APR_POOL_DEBUG_OWNER 0x08 +#define APR_POOL_DEBUG_VERBOSE_ALLOC 0x10 + +#define APR_POOL_DEBUG_VERBOSE_ALL (APR_POOL_DEBUG_VERBOSE \ + | APR_POOL_DEBUG_VERBOSE_ALLOC) + + +/* + * Structures + */ + +typedef struct cleanup_t cleanup_t; + +#if APR_POOL_DEBUG + +typedef struct debug_node_t debug_node_t; + +struct debug_node_t { + debug_node_t *next; + apr_uint32_t index; + void *beginp[64]; + void *endp[64]; +}; + +#define SIZEOF_DEBUG_NODE_T APR_ALIGN_DEFAULT(sizeof(debug_node_t)) + +#endif /* APR_POOL_DEBUG */ + +/* The ref field in the apr_pool_t struct holds a + * pointer to the pointer referencing this pool. + * It is used for parent, child, sibling management. + * Look at apr_pool_create_ex() and apr_pool_destroy() + * to see how it is used. + */ +struct apr_pool_t { + apr_pool_t *parent; + apr_pool_t *child; + apr_pool_t *sibling; + apr_pool_t **ref; + cleanup_t *cleanups; + struct process_chain *subprocesses; + apr_abortfunc_t abort_fn; + apr_hash_t *user_data; + const char *tag; + +#if !APR_POOL_DEBUG + apr_allocator_t *allocator; + apr_memnode_t *active; + apr_memnode_t *self; /* The node containing the pool itself */ + char *self_first_avail; + +#else /* APR_POOL_DEBUG */ + debug_node_t *nodes; + const char *file_line; + apr_uint32_t creation_flags; + unsigned int stat_alloc; + unsigned int stat_total_alloc; + unsigned int stat_clear; +#if APR_HAS_THREADS + apr_os_thread_t owner; + apr_thread_mutex_t *mutex; +#endif /* APR_HAS_THREADS */ +#endif /* APR_POOL_DEBUG */ +#ifdef NETWARE + apr_os_proc_t owner_proc; +#endif /* defined(NETWARE) */ +}; + +#define SIZEOF_POOL_T APR_ALIGN_DEFAULT(sizeof(apr_pool_t)) + + +/* + * Variables + */ + +static apr_byte_t apr_pools_initialized = 0; +static apr_pool_t *global_pool = NULL; + +#if !APR_POOL_DEBUG +static apr_allocator_t *global_allocator = NULL; +#endif /* !APR_POOL_DEBUG */ + +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) +static apr_file_t *file_stderr = NULL; +#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */ + +/* + * Local functions + */ + +static void run_cleanups(cleanup_t *c); +static void run_child_cleanups(cleanup_t *c); +static void free_proc_chain(struct process_chain *procs); + + +#if !APR_POOL_DEBUG +/* + * Initialization + */ + +APR_DECLARE(apr_status_t) apr_pool_initialize(void) +{ + apr_status_t rv; + + if (apr_pools_initialized++) + return APR_SUCCESS; + + if ((rv = apr_allocator_create(&global_allocator)) != APR_SUCCESS) { + apr_pools_initialized = 0; + return rv; + } + + if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL, + global_allocator)) != APR_SUCCESS) { + apr_allocator_destroy(global_allocator); + global_allocator = NULL; + apr_pools_initialized = 0; + return rv; + } + +#if APR_HAS_THREADS + { + apr_thread_mutex_t *mutex; + + if ((rv = apr_thread_mutex_create(&mutex, + APR_THREAD_MUTEX_DEFAULT, + global_pool)) != APR_SUCCESS) { + return rv; + } + + apr_allocator_set_mutex(global_allocator, mutex); + } +#endif /* APR_HAS_THREADS */ + + apr_allocator_set_owner(global_allocator, global_pool); + + return APR_SUCCESS; +} + +APR_DECLARE(void) apr_pool_terminate(void) +{ + if (!apr_pools_initialized) + return; + + apr_pools_initialized = 0; + + apr_pool_destroy(global_pool); /* This will also destroy the mutex */ + global_pool = NULL; + + global_allocator = NULL; +} + +#ifdef NETWARE +void netware_pool_proc_cleanup () +{ + apr_pool_t *pool = global_pool->child; + apr_os_proc_t owner_proc = (apr_os_proc_t)getnlmhandle(); + + while (pool) { + if (pool->owner_proc == owner_proc) { + apr_pool_destroy (pool); + pool = global_pool->child; + } + else { + pool = pool->sibling; + } + } + return; +} +#endif /* defined(NETWARE) */ + +/* + * Memory allocation + */ + APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size) { - node_t *active, *node; + apr_memnode_t *active, *node; void *mem; char *endp; @@ -475,7 +555,7 @@ return mem; } - if ((node = node_malloc(pool->allocator, size)) == NULL) { + if ((node = apr_allocator_alloc(pool->allocator, size)) == NULL) { if (pool->abort_fn) pool->abort_fn(APR_ENOMEM); @@ -509,7 +589,7 @@ APR_DECLARE(void) apr_pool_clear(apr_pool_t *pool) { - node_t *active; + apr_memnode_t *active; /* Destroy the subpools. The subpools will detach themselves from * this pool thus this loop is safe and easy. @@ -537,15 +617,14 @@ if (active->next == NULL) return; - node_free(pool->allocator, active->next); + apr_allocator_free(pool->allocator, active->next); active->next = NULL; } APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool) { - node_t *node, *active, **ref; - allocator_t *allocator; - apr_uint32_t index; + apr_memnode_t *active; + apr_allocator_t *allocator; /* Destroy the subpools. The subpools will detach themselve from * this pool thus this loop is safe and easy. @@ -564,7 +643,7 @@ #if APR_HAS_THREADS apr_thread_mutex_t *mutex; - if ((mutex = pool->parent->allocator->mutex) != NULL) + if ((mutex = apr_allocator_get_mutex(pool->parent->allocator)) != NULL) apr_thread_mutex_lock(mutex); #endif /* APR_HAS_THREADS */ @@ -583,43 +662,28 @@ allocator = pool->allocator; active = pool->self; + /* Free all the nodes in the pool (including the node holding the + * pool struct), by giving them back to the allocator. + */ + apr_allocator_free(allocator, active); + /* If this pool happens to be the owner of the allocator, free * everything in the allocator (that includes the pool struct * and the allocator). Don't worry about destroying the optional mutex * in the allocator, it will have been destroyed by the cleanup function. */ - if (allocator->owner == pool) { - for (index = 0; index < MAX_INDEX; index++) { - ref = &allocator->free[index]; - while ((node = *ref) != NULL) { - *ref = node->next; - free(node); - } - } - - ref = &active; - while ((node = *ref) != NULL) { - *ref = node->next; - free(node); - } - - return; + if (apr_allocator_get_owner(allocator) == pool) { + apr_allocator_destroy(allocator); } - - /* Free all the nodes in the pool (including the node holding the - * pool struct), by giving them back to the allocator. - */ - node_free(allocator, active); } APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, - apr_uint32_t flags) + apr_allocator_t *allocator) { apr_pool_t *pool; - node_t *node; - allocator_t *allocator, *new_allocator; + apr_memnode_t *node; *newpool = NULL; @@ -629,56 +693,27 @@ if (!abort_fn && parent) abort_fn = parent->abort_fn; - allocator = parent ? parent->allocator : &global_allocator; - if ((node = node_malloc(allocator, MIN_ALLOC - SIZEOF_NODE_T)) == NULL) { + if (allocator == NULL) + allocator = parent->allocator; + + if ((node = apr_allocator_alloc(allocator, MIN_ALLOC - SIZEOF_MEMNODE_T)) == NULL) { if (abort_fn) abort_fn(APR_ENOMEM); return APR_ENOMEM; } - if ((flags & APR_POOL_FNEW_ALLOCATOR) == APR_POOL_FNEW_ALLOCATOR) { - new_allocator = (allocator_t *)node->first_avail; - pool = (apr_pool_t *)((char *)new_allocator + SIZEOF_ALLOCATOR_T); - node->first_avail = pool->self_first_avail = (char *)pool + SIZEOF_POOL_T; - - memset(new_allocator, 0, SIZEOF_ALLOCATOR_T); - new_allocator->owner = pool; - - pool->allocator = new_allocator; - pool->active = pool->self = node; - pool->abort_fn = abort_fn; - pool->child = NULL; - pool->cleanups = NULL; - pool->subprocesses = NULL; - pool->user_data = NULL; - pool->tag = NULL; - -#if APR_HAS_THREADS - if ((flags & APR_POOL_FLOCK) == APR_POOL_FLOCK) { - apr_status_t rv; - - if ((rv = apr_thread_mutex_create(&allocator->mutex, - APR_THREAD_MUTEX_DEFAULT, pool)) != APR_SUCCESS) { - node_free(allocator, node); - return rv; - } - } -#endif /* APR_HAS_THREADS */ - } - else { - pool = (apr_pool_t *)node->first_avail; - node->first_avail = pool->self_first_avail = (char *)pool + SIZEOF_POOL_T; + pool = (apr_pool_t *)node->first_avail; + node->first_avail = pool->self_first_avail = (char *)pool + SIZEOF_POOL_T; - pool->allocator = allocator; - pool->active = pool->self = node; - pool->abort_fn = abort_fn; - pool->child = NULL; - pool->cleanups = NULL; - pool->subprocesses = NULL; - pool->user_data = NULL; - pool->tag = NULL; - } + pool->allocator = allocator; + pool->active = pool->self = node; + pool->abort_fn = abort_fn; + pool->child = NULL; + pool->cleanups = NULL; + pool->subprocesses = NULL; + pool->user_data = NULL; + pool->tag = NULL; #ifdef NETWARE pool->owner_proc = (apr_os_proc_t)getnlmhandle(); @@ -686,9 +721,12 @@ if ((pool->parent = parent) != NULL) { #if APR_HAS_THREADS - if (allocator->mutex) - apr_thread_mutex_lock(allocator->mutex); + apr_thread_mutex_t *mutex; + + if ((mutex = apr_allocator_get_mutex(allocator)) != NULL) + apr_thread_mutex_lock(mutex); #endif /* APR_HAS_THREADS */ + if ((pool->sibling = parent->child) != NULL) pool->sibling->ref = &pool->sibling; @@ -696,8 +734,8 @@ pool->ref = &parent->child; #if APR_HAS_THREADS - if (allocator->mutex) - apr_thread_mutex_unlock(allocator->mutex); + if (mutex) + apr_thread_mutex_unlock(mutex); #endif /* APR_HAS_THREADS */ } else { @@ -731,26 +769,26 @@ struct psprintf_data { apr_vformatter_buff_t vbuff; - node_t *node; - allocator_t *allocator; - apr_byte_t got_a_new_node; - node_t *free; + apr_memnode_t *node; + apr_allocator_t *allocator; + apr_byte_t got_a_new_node; + apr_memnode_t *free; }; static int psprintf_flush(apr_vformatter_buff_t *vbuff) { struct psprintf_data *ps = (struct psprintf_data *)vbuff; - node_t *node, *active; + apr_memnode_t *node, *active; apr_size_t cur_len; char *strp; - allocator_t *allocator; + apr_allocator_t *allocator; allocator = ps->allocator; node = ps->node; strp = ps->vbuff.curpos; cur_len = strp - node->first_avail; - if ((active = node_malloc(allocator, cur_len << 1)) == NULL) + if ((active = apr_allocator_alloc(allocator, cur_len << 1)) == NULL) return -1; memcpy(active->first_avail, node->first_avail, cur_len); @@ -773,7 +811,7 @@ struct psprintf_data ps; char *strp; apr_size_t size; - node_t *active; + apr_memnode_t *active; ps.node = active = pool->active; ps.allocator = pool->allocator; @@ -807,7 +845,7 @@ } if (ps.free) - node_free(ps.allocator, ps.free); + apr_allocator_free(ps.allocator, ps.free); return strp; } @@ -1831,10 +1869,10 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, - apr_uint32_t flags, + apr_allocator_t *allocator, const char *file_line) { - return apr_pool_create_ex(newpool, parent, abort_fn, flags); + return apr_pool_create_ex(newpool, parent, abort_fn, allocator); } #else /* APR_POOL_DEBUG */ The httpd stuff. Index: server/mpm/beos/beos.c =================================================================== RCS file: /home/cvspublic/httpd-2.0/server/mpm/beos/beos.c,v retrieving revision 1.85 diff -u -r1.85 beos.c --- server/mpm/beos/beos.c 21 Feb 2002 18:52:28 -0000 1.85 +++ server/mpm/beos/beos.c 4 Mar 2002 14:02:57 -0000 @@ -359,6 +359,7 @@ proc_info * ti = dummy; int child_slot = ti->slot; apr_pool_t *tpool = ti->tpool; + apr_allocator_t *allocator; apr_socket_t *csd = NULL; apr_pool_t *ptrans; /* Pool for per-transaction stuff */ apr_socket_t *sd = NULL; @@ -378,7 +379,10 @@ sigfillset(&sig_mask); sigprocmask(SIG_BLOCK, &sig_mask, NULL); - apr_pool_create_ex(&ptrans, tpool, NULL, APR_POOL_FNEW_ALLOCATOR); + apr_allocator_create(&allocator); + apr_pool_create_ex(&ptrans, tpool, NULL, allocator); + apr_allocator_set_owner(ptrans); + apr_pool_tag(ptrans, "transaction"); apr_lock_acquire(worker_thread_count_mutex); Index: server/mpm/netware/mpm_netware.c =================================================================== RCS file: /home/cvspublic/httpd-2.0/server/mpm/netware/mpm_netware.c,v retrieving revision 1.34 diff -u -r1.34 mpm_netware.c --- server/mpm/netware/mpm_netware.c 15 Feb 2002 20:48:19 -0000 1.34 +++ server/mpm/netware/mpm_netware.c 4 Mar 2002 14:03:03 -0000 @@ -351,6 +351,7 @@ ap_listen_rec *lr; ap_listen_rec *last_lr = NULL; apr_pool_t *ptrans; + apr_allocator_t *allocator; conn_rec *current_conn; apr_status_t stat = APR_EINIT; int worker_num_arg = (int)arg; @@ -368,7 +369,10 @@ tv.tv_sec = 1; tv.tv_usec = 0; - apr_pool_create_ex(&ptrans, NULL, NULL, APR_POOL_FNEW_ALLOCATOR); + apr_allocator_create(&allocator); + apr_pool_create_ex(&ptrans, NULL, NULL, allocator); + apr_allocator_set_owner(allocator, ptrans); + apr_pool_tag(ptrans, "transaction"); apr_thread_mutex_lock(worker_thread_count_mutex); Index: server/mpm/prefork/prefork.c =================================================================== RCS file: /home/cvspublic/httpd-2.0/server/mpm/prefork/prefork.c,v retrieving revision 1.246 diff -u -r1.246 prefork.c --- server/mpm/prefork/prefork.c 21 Feb 2002 18:52:28 -0000 1.246 +++ server/mpm/prefork/prefork.c 4 Mar 2002 14:03:10 -0000 @@ -518,6 +518,7 @@ static void child_main(int child_num_arg) { apr_pool_t *ptrans; + apr_allocator_t *allocator; conn_rec *current_conn; apr_status_t status = APR_EINIT; int i; @@ -537,7 +538,9 @@ /* Get a sub context for global allocations in this child, so that * we can have cleanups occur when the child exits. */ - apr_pool_create_ex(&pchild, pconf, NULL, APR_POOL_FNEW_ALLOCATOR); + apr_allocator_create(&allocator); + apr_pool_create_ex(&pchild, pconf, NULL, allocator); + apr_allocator_set_owner(allocator, pchild); apr_pool_create(&ptrans, pchild); apr_pool_tag(ptrans, "transaction"); Index: server/mpm/worker/worker.c =================================================================== RCS file: /home/cvspublic/httpd-2.0/server/mpm/worker/worker.c,v retrieving revision 1.81 diff -u -r1.81 worker.c --- server/mpm/worker/worker.c 24 Feb 2002 20:53:26 -0000 1.81 +++ server/mpm/worker/worker.c 4 Mar 2002 14:03:20 -0000 @@ -672,7 +672,11 @@ if (!workers_may_exit) { /* create a new transaction pool for each accepted socket */ if (recycled_pool == NULL) { - apr_pool_create_ex(&ptrans, NULL, NULL, APR_POOL_FNEW_ALLOCATOR); + apr_allocator_t *allocator; + + apr_allocator_create(&allocator); + apr_pool_create_ex(&ptrans, NULL, NULL, allocator); + apr_allocator_set_owner(allocator, ptrans); } else { ptrans = recycled_pool; ------=_NextPart_000_0364_01C1C42C.EBBBE7D0 Content-Type: application/octet-stream; name="apr_allocator.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="apr_allocator.h" /* = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= * The Apache Software License, Version 1.1=0A= *=0A= * Copyright (c) 2000-2002 The Apache Software Foundation. All rights=0A= * reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= *=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= *=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in=0A= * the documentation and/or other materials provided with the=0A= * distribution.=0A= *=0A= * 3. The end-user documentation included with the redistribution,=0A= * if any, must include the following acknowledgment:=0A= * "This product includes software developed by the=0A= * Apache Software Foundation (http://www.apache.org/)."=0A= * Alternately, this acknowledgment may appear in the software itself,=0A= * if and wherever such third-party acknowledgments normally appear.=0A= *=0A= * 4. The names "Apache" and "Apache Software Foundation" must=0A= * not be used to endorse or promote products derived from this=0A= * software without prior written permission. For written=0A= * permission, please contact apache@apache.org.=0A= *=0A= * 5. Products derived from this software may not be called "Apache",=0A= * nor may "Apache" appear in their name, without prior written=0A= * permission of the Apache Software Foundation.=0A= *=0A= * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED=0A= * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES=0A= * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE=0A= * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR=0A= * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,=0A= * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF=0A= * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND=0A= * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,=0A= * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT=0A= * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * This software consists of voluntary contributions made by many=0A= * individuals on behalf of the Apache Software Foundation. For more=0A= * information on the Apache Software Foundation, please see=0A= * .=0A= */=0A= =0A= #ifndef APR_ALLOCATOR_H=0A= #define APR_ALLOCATOR_H=0A= =0A= #ifdef __cplusplus=0A= extern "C" {=0A= #endif=0A= =0A= #include "apr.h"=0A= #include "apr_errno.h"=0A= =0A= typedef struct apr_allocator_t apr_allocator_t;=0A= typedef struct apr_memnode_t apr_memnode_t;=0A= =0A= #include "apr_thread_mutex.h"=0A= =0A= APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t = **allocator);=0A= =0A= APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator);=0A= =0A= #if APR_HAS_THREADS=0A= APR_DECLARE(void) apr_allocator_set_mutex(apr_allocator_t *allocator,=0A= apr_thread_mutex_t *mutex);=0A= =0A= APR_DECLARE(apr_thread_mutex_t *) apr_allocator_get_mutex(=0A= apr_allocator_t *allocator);=0A= #endif=0A= =0A= APR_DECLARE(void) apr_allocator_set_owner(apr_allocator_t *allocator,=0A= apr_pool_t *pool);=0A= =0A= APR_DECLARE(apr_pool_t *) apr_allocator_get_owner(apr_allocator_t = *allocator);=0A= =0A= APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t = *allocator,=0A= apr_size_t size);=0A= =0A= APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator,=0A= apr_memnode_t *node);=0A= =0A= =0A= #ifdef __cplusplus=0A= }=0A= #endif=0A= =0A= #endif /* !APR_ALLOCATOR_H */=0A= ------=_NextPart_000_0364_01C1C42C.EBBBE7D0--