⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apr_pools.c

📁 log4cxx 0.10 unix下编译包
💻 C
📖 第 1 页 / 共 4 页
字号:
static int pool_is_child_of(apr_pool_t *parent, void *data){    apr_pool_t *pool = (apr_pool_t *)data;    return (pool == parent);}static int apr_pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent){    if (parent == NULL)        return 0;    return apr_pool_walk_tree(parent, pool_is_child_of, pool);}#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME) */static void apr_pool_check_integrity(apr_pool_t *pool){    /* Rule of thumb: use of the global pool is always     * ok, since the only user is apr_pools.c.  Unless     * people have searched for the top level parent and     * started to use that...     */    if (pool == global_pool || global_pool == NULL)        return;    /* Lifetime     * This basically checks to see if the pool being used is still     * a relative to the global pool.  If not it was previously     * destroyed, in which case we abort().     */#if (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME)    if (!apr_pool_is_child_of(pool, global_pool)) {#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)        apr_pool_log_event(pool, "LIFE",                           __FILE__ ":apr_pool_integrity check", 0);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */        abort();    }#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME) */#if (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER)#if APR_HAS_THREADS    if (!apr_os_thread_equal(pool->owner, apr_os_thread_current())) {#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)        apr_pool_log_event(pool, "THREAD",                           __FILE__ ":apr_pool_integrity check", 0);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */        abort();    }#endif /* APR_HAS_THREADS */#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) */}/* * Initialization (debug) */APR_DECLARE(apr_status_t) apr_pool_initialize(void){    apr_status_t rv;#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)    char *logpath;#endif    if (apr_pools_initialized++)        return APR_SUCCESS;    /* Since the debug code works a bit differently then the     * regular pools code, we ask for a lock here.  The regular     * pools code has got this lock embedded in the global     * allocator, a concept unknown to debug mode.     */    if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL,                                 NULL)) != APR_SUCCESS) {        return rv;    }    apr_pool_tag(global_pool, "APR global pool");    apr_pools_initialized = 1;    /* This has to happen here because mutexes might be backed by     * atomics.  It used to be snug and safe in apr_initialize().     */    if ((rv = apr_atomic_init(global_pool)) != APR_SUCCESS) {        return rv;    }#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)    rv = apr_env_get(&logpath, "APR_POOL_DEBUG_LOG", global_pool);    if (rv == APR_SUCCESS) {        apr_file_open(&file_stderr, logpath, APR_APPEND|APR_WRITE|APR_CREATE,                      APR_OS_DEFAULT, global_pool);    }    else {        apr_file_open_stderr(&file_stderr, global_pool);    }    if (file_stderr) {        apr_file_printf(file_stderr,            "POOL DEBUG: [PID"#if APR_HAS_THREADS            "/TID"#endif /* APR_HAS_THREADS */            "] ACTION  (SIZE      /POOL SIZE /TOTAL SIZE) "            "POOL       \"TAG\" <__FILE__:__LINE__> (ALLOCS/TOTAL ALLOCS/CLEARS)\n");        apr_pool_log_event(global_pool, "GLOBAL", __FILE__ ":apr_pool_initialize", 0);    }#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */    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;#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)    file_stderr = NULL;#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */}/* * Memory allocation (debug) */static void *pool_alloc(apr_pool_t *pool, apr_size_t size){    debug_node_t *node;    void *mem;    if ((mem = malloc(size)) == NULL) {        if (pool->abort_fn)            pool->abort_fn(APR_ENOMEM);        return NULL;    }    node = pool->nodes;    if (node == NULL || node->index == 64) {        if ((node = malloc(SIZEOF_DEBUG_NODE_T)) == NULL) {            if (pool->abort_fn)                pool->abort_fn(APR_ENOMEM);            return NULL;        }        memset(node, 0, SIZEOF_DEBUG_NODE_T);        node->next = pool->nodes;        pool->nodes = node;        node->index = 0;    }    node->beginp[node->index] = mem;    node->endp[node->index] = (char *)mem + size;    node->index++;    pool->stat_alloc++;    pool->stat_total_alloc++;    return mem;}APR_DECLARE(void *) apr_palloc_debug(apr_pool_t *pool, apr_size_t size,                                     const char *file_line){    void *mem;    apr_pool_check_integrity(pool);    mem = pool_alloc(pool, size);#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALLOC)    apr_pool_log_event(pool, "PALLOC", file_line, 1);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALLOC) */    return mem;}APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *pool, apr_size_t size,                                      const char *file_line){    void *mem;    apr_pool_check_integrity(pool);    mem = pool_alloc(pool, size);    memset(mem, 0, size);#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALLOC)    apr_pool_log_event(pool, "PCALLOC", file_line, 1);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALLOC) */    return mem;}/* * Pool creation/destruction (debug) */#define POOL_POISON_BYTE 'A'static void pool_clear_debug(apr_pool_t *pool, const char *file_line){    debug_node_t *node;    apr_uint32_t index;    /* Destroy the subpools.  The subpools will detach themselves from     * this pool thus this loop is safe and easy.     */    while (pool->child)        pool_destroy_debug(pool->child, file_line);    /* Run cleanups */    run_cleanups(&pool->cleanups);    pool->free_cleanups = NULL;    pool->cleanups = NULL;    /* If new child pools showed up, this is a reason to raise a flag */    if (pool->child)        abort();    /* Free subprocesses */    free_proc_chain(pool->subprocesses);    pool->subprocesses = NULL;    /* Clear the user data. */    pool->user_data = NULL;    /* Free the blocks, scribbling over them first to help highlight     * use-after-free issues. */    while ((node = pool->nodes) != NULL) {        pool->nodes = node->next;        for (index = 0; index < node->index; index++) {            memset(node->beginp[index], POOL_POISON_BYTE,                   node->endp[index] - node->beginp[index]);            free(node->beginp[index]);        }        memset(node, POOL_POISON_BYTE, SIZEOF_DEBUG_NODE_T);        free(node);    }    pool->stat_alloc = 0;    pool->stat_clear++;}APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool,                                       const char *file_line){#if APR_HAS_THREADS    apr_thread_mutex_t *mutex = NULL;#endif    apr_pool_check_integrity(pool);#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)    apr_pool_log_event(pool, "CLEAR", file_line, 1);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */#if APR_HAS_THREADS    if (pool->parent != NULL)        mutex = pool->parent->mutex;    /* Lock the parent mutex before clearing so that if we have our     * own mutex it won't be accessed by apr_pool_walk_tree after     * it has been destroyed.     */    if (mutex != NULL && mutex != pool->mutex) {        apr_thread_mutex_lock(mutex);    }#endif    pool_clear_debug(pool, file_line);#if APR_HAS_THREADS    /* If we had our own mutex, it will have been destroyed by     * the registered cleanups.  Recreate the mutex.  Unlock     * the mutex we obtained above.     */    if (mutex != pool->mutex) {        (void)apr_thread_mutex_create(&pool->mutex,                                      APR_THREAD_MUTEX_NESTED, pool);        if (mutex != NULL)            (void)apr_thread_mutex_unlock(mutex);    }#endif /* APR_HAS_THREADS */}static void pool_destroy_debug(apr_pool_t *pool, const char *file_line){    apr_pool_check_integrity(pool);#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)    apr_pool_log_event(pool, "DESTROY", file_line, 1);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */    pool_clear_debug(pool, file_line);    /* Remove the pool from the parents child list */    if (pool->parent) {#if APR_HAS_THREADS        apr_thread_mutex_t *mutex;        if ((mutex = pool->parent->mutex) != NULL)            apr_thread_mutex_lock(mutex);#endif /* APR_HAS_THREADS */        if ((*pool->ref = pool->sibling) != NULL)            pool->sibling->ref = pool->ref;#if APR_HAS_THREADS        if (mutex)            apr_thread_mutex_unlock(mutex);#endif /* APR_HAS_THREADS */    }    if (pool->allocator != NULL        && apr_allocator_owner_get(pool->allocator) == pool) {        apr_allocator_destroy(pool->allocator);    }    /* Free the pool itself */    free(pool);}APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *pool,                                         const char *file_line){    if (pool->joined) {        /* Joined pools must not be explicitly destroyed; the caller         * has broken the guarantee. */#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)        apr_pool_log_event(pool, "LIFE",                           __FILE__ ":apr_pool_destroy abort on joined", 0);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */        abort();    }    pool_destroy_debug(pool, file_line);}APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool,                                                   apr_pool_t *parent,                                                   apr_abortfunc_t abort_fn,                                                   apr_allocator_t *allocator,                                                   const char *file_line){    apr_pool_t *pool;    *newpool = NULL;    if (!parent) {        parent = global_pool;    }    else {       apr_pool_check_integrity(parent);       if (!allocator)           allocator = parent->allocator;    }    if (!abort_fn && parent)        abort_fn = parent->abort_fn;    if ((pool = malloc(SIZEOF_POOL_T)) == NULL) {        if (abort_fn)            abort_fn(APR_ENOMEM);         return APR_ENOMEM;    }    memset(pool, 0, SIZEOF_POOL_T);    pool->allocator = allocator;    pool->abort_fn = abort_fn;    pool->tag = file_line;    pool->file_line = file_line;    if ((pool->parent = parent) != NULL) {#if APR_HAS_THREADS        if (parent->mutex)            apr_thread_mutex_lock(parent->mutex);#endif /* APR_HAS_THREADS */        if ((pool->sibling = parent->child) != NULL)            pool->sibling->ref = &pool->sibling;        parent->child = pool;        pool->ref = &parent->child;#if APR_HAS_THREADS        if (parent->mutex)            apr_thread_mutex_unlock(parent->mutex);#endif /* APR_HAS_THREADS */    }    else {        pool->sibling = NULL;        pool->ref = NULL;    }#if APR_HAS_THREADS    pool->owner = apr_os_thread_current();#endif /* APR_HAS_THREADS */#ifdef NETWARE    pool->owner_proc = (apr_os_proc_t)getnlmhandle();#endif /* defined(NETWARE) */    if (parent == NULL || parent->allocator != allocator) {#if APR_HAS_THREADS        apr_status_t rv;        /* No matter what the creation flags say, always create         * a lock.  Without it integrity_check and apr_pool_num_bytes         * blow up (because they traverse pools child lists that         * possibly belong to another thread, in combination with         * the pool having no lock).  However, this might actually         * hide problems like creating a child pool of a pool         * belonging to another thread.         */        if ((rv = apr_thread_mutex_create(&pool->mutex,                APR_THREAD_MUTEX_NESTED, pool)) != APR_SUCCESS) {            free(pool);            return rv;        }#endif /* APR_HAS_THREADS */    }    else {#if APR_HAS_THREADS        if (parent)            pool->mutex = parent->mutex;#endif /* APR_HAS_THREADS */    }    *newpool = pool;#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)    apr_pool_log_event(pool, "CREATE", file_line, 1);#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */    return APR_SUCCESS;}/* * "Print" functions (debug) */struct psprintf_data {    apr_vformatter_buff_t vbuff;    char      *mem;    apr_size_t size;};static int psprintf_flush(apr_vformatter_buff_t *vbuff){    struct psprintf_data *ps = (struct psprintf_data *)vbuff;    apr_size_t size;    size = ps->vbuff.curpos - ps->mem;    ps->size <<= 1;    if ((ps->mem = realloc(ps->mem, ps->size)) == NULL)        return -1;    ps->vbuff.curpos = ps->mem + size;    ps->vbuff.endpos = ps->mem + ps->size - 1;    return 0;}APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap){    struct psprintf_data ps;    debug_node_t *node;    apr_pool_check_integrity(pool);    ps.size = 64;    ps.mem = malloc(ps.size);    ps.vbuff.curpos  = ps.mem;    /* Save a byte for the NUL terminator */    ps.vbuff.endpos = ps.mem + ps.size - 1;    if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1) {        if (pool->abort_fn)            pool->abort_fn(APR_ENOMEM);        return NULL;    }    *ps.vbuff.curpos++ = '\0';    /*     * Link the node in     */    node = pool->nodes;    if (node == NULL || node->index == 64) {        if ((node = malloc(SIZEOF_DEBUG_NODE_T)) == NULL) {            if (pool->abort_fn)                pool->abort_fn(APR_ENOMEM);            return NULL;        }        node->next = pool->nodes;        pool->nodes = node;        node->index = 0;    }    node->beginp[node->index] = ps.mem;    node->endp[node->index] = ps.mem + ps.size;    node->index++;    return ps.mem;}/* * Debug functions */APR_DECLARE(void) apr_pool_join(apr_pool_t *p, apr_pool_t *sub){#if APR_POOL_DEBUG    if (sub->parent != p) {        abort();    }    sub->joined = p;#endif}static int pool_find(apr_pool_t *pool, void *data){    void **pmem = (void **)data;    debug_node_t *node;    apr_uint32_t index;    node = pool->nodes;    while (node) {        for (index = 0; index < node->index; index++) {             if (node->beginp[index] <= *pmem                 && node->endp[index] > *pmem) {                 *pmem = pool;                 return 1;             }        }        node = node->next;    }    return 0;}APR_DECLARE(apr_pool_t *) apr_pool_find(const void *mem)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -