striker 02/03/14 16:48:24
Modified: include apr_pools.h apr_thread_mutex.h
memory/unix apr_pools.c
Added: include apr_allocator.h
Log:
Factor out the allocators from pools.
Revision Changes Path
1.80 +16 -20 apr/include/apr_pools.h
Index: apr_pools.h
===================================================================
RCS file: /home/cvs/apr/include/apr_pools.h,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- apr_pools.h 13 Mar 2002 20:39:14 -0000 1.79
+++ apr_pools.h 15 Mar 2002 00:48:24 -0000 1.80
@@ -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,24 +132,15 @@
#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);
-/** Pool creation flags */
-#define APR_POOL_FDEFAULT 0x0
-#define APR_POOL_FNEW_ALLOCATOR 0x1
-#define APR_POOL_FLOCK 0x2
+/** A function that is called when allocation fails. */
+typedef int (*apr_abortfunc_t)(int retcode);
/*
* APR memory structure manipulators (pools, tables, and arrays).
@@ -193,7 +189,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,12 +210,12 @@
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
-#define apr_pool_create_ex(newpool, parent, abort_fn, flag) \
- apr_pool_create_ex_debug(newpool, parent, abort_fn, flag, \
+#define apr_pool_create_ex(newpool, parent, abort_fn, allocator) \
+ apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator, \
APR_POOL__FILE_LINE__)
#endif
@@ -237,11 +233,11 @@
#else
#if APR_POOL_DEBUG
#define apr_pool_create(newpool, parent) \
- apr_pool_create_ex_debug(newpool, parent, NULL, APR_POOL_FDEFAULT, \
+ apr_pool_create_ex_debug(newpool, parent, NULL, NULL, \
APR_POOL__FILE_LINE__)
#else
#define apr_pool_create(newpool, parent) \
- apr_pool_create_ex(newpool, parent, NULL, APR_POOL_FDEFAULT)
+ apr_pool_create_ex(newpool, parent, NULL, NULL)
#endif
#endif
@@ -256,11 +252,11 @@
#if APR_POOL_DEBUG
#define apr_pool_sub_make(newpool, parent, abort_fn) \
(void)apr_pool_create_ex_debug(newpool, parent, abort_fn, \
- APR_POOL_FDEFAULT, \
+ NULL, \
APR_POOL__FILE_LINE__)
#else
#define apr_pool_sub_make(newpool, parent, abort_fn) \
- (void)apr_pool_create_ex(newpool, parent, abort_fn, APR_POOL_FDEFAULT)
+ (void)apr_pool_create_ex(newpool, parent, abort_fn, NULL)
#endif
/**
1.8 +11 -1 apr/include/apr_thread_mutex.h
Index: apr_thread_mutex.h
===================================================================
RCS file: /home/cvs/apr/include/apr_thread_mutex.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- apr_thread_mutex.h 13 Mar 2002 20:39:15 -0000 1.7
+++ apr_thread_mutex.h 15 Mar 2002 00:48:24 -0000 1.8
@@ -127,7 +127,17 @@
* Get the pool used by this thread_mutex.
* @return apr_pool_t the pool
*/
-APR_POOL_DECLARE_ACCESSOR(thread_mutex);
+/*
+ * XXX: We should do:
+ *
+ * APR_POOL_DECLARE_ACCESSOR(thread_mutex);
+ *
+ * But since there is a dependency between apr_thread_mutex.h, apr_pools.h
+ * and apr_allocator.h, this won't work without lots of warnings. Spelling
+ * it out resolves the problem.
+ */
+APR_DECLARE(apr_pool_t *) apr_thread_mutex_pool_get (const
apr_thread_mutex_t *ob);
+
#endif /* APR_HAS_THREADS */
1.1 apr/include/apr_allocator.h
Index: apr_allocator.h
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#ifndef APR_ALLOCATOR_H
#define APR_ALLOCATOR_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file apr_allocator.h
* @brief APR memory allocation
*
*/
#include "apr.h"
#include "apr_errno.h"
#define APR_WANT_MEMFUNC
#include "apr_want.h"
#include "apr_thread_mutex.h"
#include "apr_pools.h"
typedef struct apr_allocator_t apr_allocator_t;
typedef struct apr_memnode_t apr_memnode_t;
/**
* Create a new allocator
* @param allocator The allocator we have just created.
*
*/
APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator);
/**
* Destroy an allocator
* @param allocator The allocator to be destroyed
* @remark Any memnodes not given back to the allocator prior to destroying
* will _not_ be free()d.
*/
APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator);
/**
* Allocate a block of mem from the allocator
* @param allocator The allocator to allocate from
* @param size The size of the mem to allocate (excluding the
* memnode structure)
*/
/*
* XXX: Move this to a private header file
*/
APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator,
apr_size_t size);
/**
* Free a block of mem, giving it back to the allocator
* @param allocator The allocator to give the mem back to
* @param memnode The memory node to return
*/
/*
* XXX: Move this to a private header file
*/
APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator,
apr_memnode_t *memnode);
/**
* Set the owner of the allocator
* @param allocator The allocator to set the owner for
* @param pool The pool that is to own the allocator
* @remark Typically pool is the highest level pool using the allocator
*/
/*
* XXX: see if we can come up with something a bit better. Currently
* you can make a pool an owner, but if the pool doesn't use the allocator
* the allocator will never be destroyed.
*/
APR_DECLARE(void) apr_allocator_set_owner(apr_allocator_t *allocator,
apr_pool_t *pool);
/**
* Get the current owner of the allocator
* @param allocator The allocator to get the owner from
*/
APR_DECLARE(apr_pool_t *) apr_allocator_get_owner(apr_allocator_t *allocator);
#if APR_HAS_THREADS
/**
* Set a mutex for the allocator to use
* @param allocator The allocator to set the mutex for
* @param mutex The mutex
*/
APR_DECLARE(void) apr_allocator_set_mutex(apr_allocator_t *allocator,
apr_thread_mutex_t *mutex);
/**
* Get the mutex currently set for the allocator
* @param allocator The allocator
*/
APR_DECLARE(apr_thread_mutex_t *) apr_allocator_get_mutex(
apr_allocator_t *allocator);
#endif /* APR_HAS_THREADS */
#ifdef __cplusplus
}
#endif
#endif /* !APR_ALLOCATOR_H */
1.159 +323 -274 apr/memory/unix/apr_pools.c
Index: apr_pools.c
===================================================================
RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
retrieving revision 1.158
retrieving revision 1.159
diff -u -r1.158 -r1.159
--- apr_pools.c 14 Mar 2002 22:18:16 -0000 1.158
+++ apr_pools.c 15 Mar 2002 00:48:24 -0000 1.159
@@ -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,208 +101,95 @@
/*
- * Structures
+ * Allocator
*/
-typedef struct cleanup_t cleanup_t;
-
-/** A list of processes */
-struct process_chain {
- /** The process ID */
- apr_proc_t *pid;
- apr_kill_conditions_e kill_how;
- /** The next process in the list */
- struct process_chain *next;
-};
-
-#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;
-
- if (apr_pools_initialized++)
- return APR_SUCCESS;
+ apr_allocator_t *new_allocator;
- memset(&global_allocator, 0, sizeof(global_allocator));
+ *allocator = NULL;
- if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL,
APR_POOL_FDEFAULT)) != APR_SUCCESS) {
- return rv;
- }
+ if ((new_allocator = malloc(SIZEOF_ALLOCATOR_T)) == NULL)
+ return APR_ENOMEM;
-#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 */
+ memset(new_allocator, 0, SIZEOF_ALLOCATOR_T);
- 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;
@@ -359,7 +247,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;
}
@@ -395,7 +283,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;
}
@@ -414,15 +302,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
@@ -466,9 +355,203 @@
#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;
+
+/** A list of processes */
+struct process_chain {
+ /** The process ID */
+ apr_proc_t *pid;
+ apr_kill_conditions_e kill_how;
+ /** The next process in the list */
+ struct process_chain *next;
+};
+
+
+#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;
+ apr_allocator_t *allocator;
+ struct process_chain *subprocesses;
+ apr_abortfunc_t abort_fn;
+ apr_hash_t *user_data;
+ const char *tag;
+
+#if !APR_POOL_DEBUG
+ 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;
+
+ if (--apr_pools_initialized)
+ return;
+
+ 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;
@@ -484,7 +567,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);
@@ -518,7 +601,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.
@@ -546,15 +629,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.
@@ -573,7 +655,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 */
@@ -592,43 +674,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;
@@ -638,56 +705,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();
@@ -695,9 +733,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;
@@ -705,8 +746,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 {
@@ -740,26 +781,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);
@@ -782,7 +823,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;
@@ -816,7 +857,7 @@
}
if (ps.free)
- node_free(ps.allocator, ps.free);
+ apr_allocator_free(ps.allocator, ps.free);
return strp;
}
@@ -868,10 +909,10 @@
return rv;
}
+#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)
static void apr_pool_log_event(apr_pool_t *pool, const char *event,
const char *file_line, int deref)
{
-#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)
if (file_stderr) {
if (deref) {
apr_file_printf(file_stderr,
@@ -921,8 +962,8 @@
file_line);
}
}
-#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */
}
+#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */
static int pool_is_child_of(apr_pool_t *parent, void *data)
{
@@ -992,7 +1033,7 @@
* allocator, a concept unknown to debug mode.
*/
if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL,
- APR_POOL_FNEW_ALLOCATOR|APR_POOL_FLOCK)) != APR_SUCCESS) {
+ NULL)) != APR_SUCCESS) {
return rv;
}
@@ -1191,6 +1232,11 @@
#endif /* APR_HAS_THREADS */
}
+ if (pool->allocator != NULL
+ && apr_allocator_get_owner(pool->allocator) == pool) {
+ apr_allocator_destroy(pool->allocator);
+ }
+
/* Free the pool itself */
free(pool);
}
@@ -1198,7 +1244,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)
{
apr_pool_t *pool;
@@ -1210,6 +1256,9 @@
}
else {
apr_pool_check_integrity(parent);
+
+ if (!allocator)
+ allocator = parent->allocator;
}
if (!abort_fn && parent)
@@ -1224,10 +1273,10 @@
memset(pool, 0, SIZEOF_POOL_T);
+ pool->allocator = allocator;
pool->abort_fn = abort_fn;
pool->tag = file_line;
pool->file_line = file_line;
- pool->creation_flags = flags;
if ((pool->parent = parent) != NULL) {
#if APR_HAS_THREADS
@@ -1254,7 +1303,7 @@
pool->owner = apr_os_thread_current();
#endif /* APR_HAS_THREADS */
- if ((flags & APR_POOL_FNEW_ALLOCATOR) == APR_POOL_FNEW_ALLOCATOR) {
+ if (parent != NULL || parent->allocator != allocator) {
#if APR_HAS_THREADS
apr_status_t rv;
@@ -1840,10 +1889,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 */
@@ -1884,15 +1933,15 @@
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_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)
{
return apr_pool_create_ex_debug(newpool, parent,
- abort_fn, flags,
+ abort_fn, allocator,
"undefined");
}