/* ==================================================================== * 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 apache@apache.org. * * 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 * . */ /* This code kindly donated to APR by * Elrond * Luke Kenneth Casson Leighton * Sander Striker * * May 2001 */ #ifndef APR_MEMORY_SYSTEM_H #define APR_MEMORY_SYSTEM_H #include "apr.h" #include "apr_errno.h" #include "apr_pools.h" #include "apr_lock.h" #ifdef __cplusplus extern "C" { #endif /* The various types of cleanup's we can offer */ #define APR_ALL_CLEANUPS 0x0000 #define APR_CHILD_CLEANUP 0x0001 #define APR_PARENT_CLEANUP 0x0002 /* Alignment macro's */ #define APR_ALIGN(size, boundary) \ ((size) + (((boundary) - ((size) & ((boundary) - 1))) & ((boundary) - 1))) #define APR_ALIGN_DEFAULT(size) APR_ALIGN(size, 8) /** * @package APR memory system */ struct apr_sms_cleanup; typedef struct apr_sms_t apr_sms_t; /** * The memory system structure */ struct apr_sms_t { apr_sms_t *parent; apr_sms_t *child; apr_sms_t *sibling; apr_sms_t **ref; apr_sms_t *accounting; const char *identity; /* a string identifying the module */ apr_pool_t *pool; apr_lock_t *sms_lock; struct apr_sms_cleanup *cleanups; void * (*malloc_fn) (apr_sms_t *sms, apr_size_t size); void * (*calloc_fn) (apr_sms_t *sms, apr_size_t size); void * (*realloc_fn) (apr_sms_t *sms, void *memory, apr_size_t size); apr_status_t (*free_fn) (apr_sms_t *sms, void *memory); apr_status_t (*reset_fn) (apr_sms_t *sms); apr_status_t (*pre_destroy_fn) (apr_sms_t *sms); apr_status_t (*destroy_fn) (apr_sms_t *sms); apr_status_t (*lock_fn) (apr_sms_t *sms); apr_status_t (*unlock_fn) (apr_sms_t *sms); }; /* * memory allocation functions */ /** * Allocate a block of memory using a certain memory system * @param sms The memory system to use * @param size The (minimal required) size of the block to be allocated * @return pointer to a newly allocated block of memory, NULL if insufficient * memory available * @deffunc void *apr_sms_malloc(apr_sms_t *sms, apr_size_t size) */ APR_DECLARE(void *) apr_sms_malloc(apr_sms_t *sms, apr_size_t size); /** * Allocate a block of zeroed memory using a certain memory system * @param sms The memory system to use * @param size The (minimal required) size of the block to be allocated * @return pointer to a newly allocated block of memory, NULL if insufficient * memory available * @deffunc void *apr_sms_calloc(apr_sms_t *sms, apr_size_t size) */ APR_DECLARE(void *) apr_sms_calloc(apr_sms_t *sms, apr_size_t size); /** * Change the size of a previously allocated block of memory * @param sms The memory system to use (should be the same as the * one that returned the block) * @param mem Pointer to the previously allocated block. If NULL, this * function acts like apr_sms_malloc. * @param size The (minimal required) size of the block to be allocated * @return pointer to a newly allocated block of memory, NULL if insufficient * memory available * @deffunc void *apr_sms_realloc(apr_sms_t *sms, void *mem, apr_size_t size) */ APR_DECLARE(void *) apr_sms_realloc(apr_sms_t *sms, void *mem, apr_size_t size); /** * Free a block of memory * @param sms The memory system to use (should be the same as the * one that returned the block) * @param mem The block of memory to be freed * @deffunc void apr_sms_free(apr_sms_t *sms, * void *mem) */ APR_DECLARE(apr_status_t) apr_sms_free(apr_sms_t *sms, void *mem); /* * memory system functions */ /** * Initialize a memory system * @caution Call this function as soon as you have obtained a block of memory * to serve as a memory system structure from your * apr_xxx_sms_create. Only use this function when you are * implementing a memory system. * @param sms The memory system created * @param parent_sms The parent memory system * @deffunc apr_status_t apr_sms_init(apr_sms_t *sms, * apr_sms_t *parent_sms) */ APR_DECLARE(apr_status_t) apr_sms_init(apr_sms_t *sms, apr_sms_t *parent_sms); /** * Check if a memory system is obeying all rules. * @caution Call this function as the last statement before returning a new * memory system from your apr_xxx_sms_create. * @deffunc void apr_sms_validate(apr_sms_t *sms) */ #ifdef APR_ASSERT_MEMORY APR_DECLARE(void) apr_sms_assert(apr_sms_t *sms); #else #ifdef apr_sms_assert #undef apr_sms_assert #endif #define apr_sms_assert(sms) #endif /* APR_ASSERT_MEMORY */ /** * Reset a memory system so it can be reused. * This will also run all cleanup functions associated with the memory system * @warning This function will fail if there is no reset function available * for the given memory system (i.e. the memory system is non- * tracking). * @param sms The memory system to be reset * @deffunc apr_status_t apr_sms_reset(apr_sms_t *sms) */ APR_DECLARE(apr_status_t) apr_sms_reset(apr_sms_t *sms); /** * Destroy a memory system, effectively freeing all of its memory, and itself. * This will also run all cleanup functions associated with the memory system. * @caution Be carefull when using this function with a non-tracking memory * system * @param sms The memory system to be destroyed * @deffunc apr_status_t apr_sms_destroy(apr_sms_t *sms) */ APR_DECLARE(apr_status_t) apr_sms_destroy(apr_sms_t *sms); /** * Perform thread-safe locking required whilst this memory system is modified * @param sms The memory system to be locked for thread-safety */ APR_DECLARE(apr_status_t) apr_sms_lock(apr_sms_t *sms); /** * Release thread-safe locking required whilst this memory system was * being modified * @param sms The memory system to be released from thread-safety */ APR_DECLARE(apr_status_t) apr_sms_unlock(apr_sms_t *sms); /** * Determine if memory system a is an ancestor of memory system b * @param a The memory system to search * @param b The memory system to search for * @return APR_SUCCESS if a is an ancestor of b, 1 if it isn't * @deffunc apr_status_t apr_sms_is_ancestor(apr_sms_t *a, * apr_sms_t *b) */ APR_DECLARE(apr_status_t) apr_sms_is_ancestor(apr_sms_t *a, apr_sms_t *b); /** * Get the memory_system identity * @param sms The memory system to use * @deffunc const char * apr_sms_identity(apr_sms_t *sms); */ APR_DECLARE(const char *) apr_sms_identity(apr_sms_t *sms); /** * Get the parent sms * @param sms the memory system to get the parent from */ APR_DECLARE(apr_sms_t *) apr_sms_get_parent(apr_sms_t *sms); /* * memory system cleanup management functions */ /** * Register a function to be called when a memory system is reset or destroyed * @param sms The memory system to register the cleanup function with * @param type The type of cleanup to register * @param data The data to pass to the cleanup function * @param cleanup_fn The function to call when the memory system is reset or * destroyed * @deffunc void apr_sms_cleanup_register(apr_sms_t *sms, apr_int32_t type, * void *data, apr_status_t (*cleanup_fn)(void *)); */ APR_DECLARE(apr_status_t) apr_sms_cleanup_register(apr_sms_t *sms, apr_int32_t type, void *data, apr_status_t (*cleanup_fn)(void *)); /** * Unregister a previously registered cleanup function * @param sms The memory system the cleanup function is registered * with * @param type The type of the cleanup to unregister * @param data The data associated with the cleanup function * @param cleanup_fn The registered cleanup function * @deffunc void apr_sms_cleanup_unregister(apr_sms_t *sms, * void *data, apr_status_t (*cleanup_fn)(void *)); */ APR_DECLARE(apr_status_t) apr_sms_cleanup_unregister(apr_sms_t *sms, apr_int32_t type, void *data, apr_status_t (*cleanup)(void *)); /** * Unregister all previously registered cleanup functions of the specified type * @param sms The memory system the cleanup functions are registered with * @param type The type associated with the cleanup function. Pass 0 to * unregister all cleanup functions. * @deffunc apr_status_t apr_sms_cleanup_unregister_type(apr_sms_t *sms, * apr_int32_t type); */ APR_DECLARE(apr_status_t) apr_sms_cleanup_unregister_type(apr_sms_t *sms, apr_int32_t type); /** * Run the specified cleanup function immediately and unregister it * @param sms The memory system the cleanup function is registered * with * @param sms The memory system the cleanup function is registered with * @param type The type associated with the cleanup function. Pass 0 to ignore type. * @param data The data associated with the cleanup function * @param cleanup The registered cleanup function * @deffunc apr_status_t apr_sms_cleanup_run(apr_sms_t *sms, * apr_int32_t type, void *data, apr_status_t (*cleanup)(void *)); */ APR_DECLARE(apr_status_t) apr_sms_cleanup_run(apr_sms_t *sms, apr_int32_t type, void *data, apr_status_t (*cleanup)(void *)); /** * Run the specified type of cleanup functions immediately and unregister them * @param sms The memory system the cleanup functions are registered with * @param type The category of cleanup functions to run. Pass 0 to run all * cleanup functions. * @deffunc apr_status_t apr_sms_cleanup_run_type(apr_sms_t *sms, * apr_int32_t type); */ APR_DECLARE(apr_status_t) apr_sms_cleanup_run_type(apr_sms_t *sms, apr_int32_t type); /** * Create a standard malloc/realloc/free memory system * @param sms A pointer to the created apr_sms_t* * @deffunc apr_status_t apr_sms_std_create(apr_sms_t **sms); */ APR_DECLARE(apr_status_t) apr_sms_std_create(apr_sms_t **sms); #ifdef __cplusplus } #endif #endif /* !APR_MEMORY_SYSTEM_H */