/* ==================================================================== * 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 */ /** * @file apr_sms.h * @brief APR SMS Memory routines */ /** * @defgroup SMS SMS Stackable Memory allocation system * @ingroup APR * @{ */ #ifndef APR_SMS_H #define APR_SMS_H /** * @typedef apr_sms_t * @brief holds the internal details required to implement a SMS * @see sms_private.h */ typedef struct apr_sms_t apr_sms_t; #include "apr.h" #include "apr_errno.h" #ifndef APR_POOLS_ARE_SMS #include "apr_pools.h" #endif #ifdef __cplusplus extern "C" { #endif #ifdef APR_POOLS_ARE_SMS typedef struct apr_sms_t apr_pool_t; typedef int (*apr_abortfunc_t)(int retcode); #endif /********************************************************************** ** Defines **********************************************************************/ /* The various types of cleanup's we can offer */ #define APR_ALL_CLEANUPS 0x0000 #define APR_GENERAL_CLEANUP 0x0001 #define APR_CHILD_CLEANUP 0x0002 /* Alignment macro's * * APR_ALIGN is only to be used to align on a power of 2 boundary */ #define APR_ALIGN(size, boundary) \ (((size) + ((boundary) - 1)) & ~((boundary) - 1)) #define APR_ALIGN_DEFAULT(size) APR_ALIGN(size, 8) /********************************************************************** ** Debug options **********************************************************************/ /* * One of the aims of SMS is to provide a large range of debugging * options. * * The options are normally turned off by having the define commented out. * To use, simply remove the define and rebuild! * * Function definitions are at the end of the file... */ /* APR_DEBUG_TO_FILE * This will put all debug output into a file, that you can name * using the APR_DEBUG_FILE define. Normally this is set to setdout * and the output is simply printed there. */ #define APR_DEBUG_TO_FILE 0 #define APR_DEBUG_FILE "/tmp/sms_debug" /* APR_DEBUG_SHOW_STRUCTURE * This turns on a print of the ancestory of the SMS when * creating/destroying an SMS so its place in the world can be seen. */ #define APR_DEBUG_SHOW_STRUCTURE 0 /* APR_DEBUG_SHOW_FUNCTIONS * This turns on debug printing of every call to * apr_sms_create * apr_sms_destroy * apr_sms_reset * * Format of output is * CREATE - sms 0x0000000 [STANDARD] has been created */ #define APR_DEBUG_SHOW_FUNCTIONS 0 /* APR_DEBUG_TAG_SMS * Turn on the ability to give an SMS a "tag" that can be used to identify * it. */ #define APR_DEBUG_TAG_SMS 0 /* APR_DEBUG_ALLOCATIONS * This will record ALL calls made to * apr_sms_malloc * apr_sms_calloc * apr_sms_realloc * apr_sms_free * Details are put into the file specified in the APR_DEBUG_ALLOC_FILE * define */ #define APR_DEBUG_ALLOCATIONS 0 #define APR_DEBUG_ALLOC_FILE "/tmp/sms_alloc" /** * @package APR memory system */ struct apr_sms_cleanup; /* * 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 */ 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 */ 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 */ 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 */ APR_DECLARE(apr_status_t) apr_sms_free(apr_sms_t *sms, void *mem); /* * memory system functions */ #ifdef APR_ASSERT_MEMORY /** * 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. */ 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 */ 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 */ 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 */ 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 identify */ APR_DECLARE(const char *) apr_sms_get_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); /** * Set the abort function. This is called when we fail to * fulfil an allocation request. * @tip If an app wants APR to exit on a memory allocation error * then this function can be called to set the callback to * use. If this function is not called then APR will return an error * and expect the app to deal with it. * @param abortfunc The function to call * @param sms The sms to register the function with */ APR_DECLARE(void) apr_sms_set_abort(apr_abortfunc_t abortfunc, apr_sms_t *sms); /** * Get the abort function registered with the sms. * @param sms The sms to get the function for * @return The abort function registered */ APR_DECLARE(apr_abortfunc_t) apr_sms_get_abort(apr_sms_t *sms); /** * Set user data into the current sms. * @param data The user data to insert * @param key The key to assign to this data * @param cleanup The cleanup program to use when cleaning up the data * @param sms The sms to inert the data into */ APR_DECLARE(apr_status_t) apr_sms_userdata_set(const void *data, const char *key, apr_status_t (*cleanup)(void*), apr_sms_t *sms); /** * Get user data from an sms using the key it was registered with * @param data A pointer to the returned data * @param key The key to use to identify the data * @param sms The sms to get the data from */ APR_DECLARE(apr_status_t) apr_sms_userdata_get(void **data, const char *key, 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 */ APR_DECLARE(apr_status_t) apr_sms_cleanup_register(apr_sms_t *sms, apr_int32_t type, const 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 type The type of cleanup to run * @param data The data associated with the cleanup function * @param cleanup_fn The registered cleanup function */ APR_DECLARE(apr_status_t) apr_sms_cleanup_unregister(apr_sms_t *sms, apr_int32_t type, const 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. */ 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 */ APR_DECLARE(apr_status_t) apr_sms_cleanup_run(apr_sms_t *sms, apr_int32_t type, const 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. */ APR_DECLARE(apr_status_t) apr_sms_cleanup_run_type(apr_sms_t *sms, apr_int32_t type); /********************************************************************** ** Standard SMS module **********************************************************************/ /** * Create a standard malloc/realloc/free memory system * @param sms A pointer to the created apr_sms_t* */ APR_DECLARE(apr_status_t) apr_sms_std_create(apr_sms_t **sms); /********************************************************************** ** Debug routines **********************************************************************/ /* NB These are only available if the debugging option has been turned on. */ #if APR_DEBUG_SHOW_STRUCTURE /** * Show the heirachy of the sms * @param sms The sms to show the information for * @param direction Do we show up (to parent) or down (to children) */ APR_DECLARE(void) apr_sms_show_structure(apr_sms_t *sms, int direction); #endif /* APR_DEBUG_SHOW_STRUCTURE */ #if APR_DEBUG_TAG_SMS /** * Set the debugging tag for an sms * @param tag The tag to give the sms * @param sms The sms to apply the tag to */ APR_DECLARE(void) apr_sms_tag(apr_sms_t *sms, const char *tag); #endif /* APR_DEBUG_TAG_SMS */ #if APR_SMS_ALLOC_STATS APR_DECLARE(void) apr_sms_dump_stats(apr_sms_t *sms); #endif #ifdef __cplusplus } #endif /** @} */ #endif /* !APR_SMS_H */