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

📄 apr_pools.c

📁 log4cxx 0.10 unix下编译包
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Node list management helper macros; list_insert() inserts 'node' * before 'point'. */#define list_insert(node, point) do {           \    node->ref = point->ref;                     \    *node->ref = node;                          \    node->next = point;                         \    point->ref = &node->next;                   \} while (0)/* list_remove() removes 'node' from its list. */#define list_remove(node) do {                  \    *node->ref = node->next;                    \    node->next->ref = node->ref;                \} while (0)/* * Memory allocation */APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size){    apr_memnode_t *active, *node;    void *mem;    apr_size_t free_index;    size = APR_ALIGN_DEFAULT(size);    active = pool->active;    /* If the active node has enough bytes left, use it. */    if (size < (apr_size_t)(active->endp - active->first_avail)) {        mem = active->first_avail;        active->first_avail += size;        return mem;    }    node = active->next;    if (size < (apr_size_t)(node->endp - node->first_avail)) {        list_remove(node);    }    else {        if ((node = allocator_alloc(pool->allocator, size)) == NULL) {            if (pool->abort_fn)                pool->abort_fn(APR_ENOMEM);            return NULL;        }    }    node->free_index = 0;    mem = node->first_avail;    node->first_avail += size;    list_insert(node, active);    pool->active = node;    free_index = (APR_ALIGN(active->endp - active->first_avail + 1,                            BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;    active->free_index = (APR_UINT32_TRUNC_CAST)free_index;    node = active->next;    if (free_index >= node->free_index)        return mem;    do {        node = node->next;    }    while (free_index < node->free_index);    list_remove(active);    list_insert(active, node);    return mem;}/* Provide an implementation of apr_pcalloc for backward compatibility * with code built before apr_pcalloc was a macro */#ifdef apr_pcalloc#undef apr_pcalloc#endifAPR_DECLARE(void *) apr_pcalloc(apr_pool_t *pool, apr_size_t size);APR_DECLARE(void *) apr_pcalloc(apr_pool_t *pool, apr_size_t size){    void *mem;    size = APR_ALIGN_DEFAULT(size);    if ((mem = apr_palloc(pool, size)) != NULL) {        memset(mem, 0, size);    }    return mem;}/* * Pool creation/destruction */APR_DECLARE(void) apr_pool_clear(apr_pool_t *pool){    apr_memnode_t *active;    /* Destroy the subpools.  The subpools will detach themselves from     * this pool thus this loop is safe and easy.     */    while (pool->child)        apr_pool_destroy(pool->child);    /* Run cleanups */    run_cleanups(&pool->cleanups);    pool->cleanups = NULL;    pool->free_cleanups = NULL;    /* Free subprocesses */    free_proc_chain(pool->subprocesses);    pool->subprocesses = NULL;    /* Clear the user data. */    pool->user_data = NULL;    /* Find the node attached to the pool structure, reset it, make     * it the active node and free the rest of the nodes.     */    active = pool->active = pool->self;    active->first_avail = pool->self_first_avail;    if (active->next == active)        return;    *active->ref = NULL;    allocator_free(pool->allocator, active->next);    active->next = active;    active->ref = &active->next;}APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool){    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.     */    while (pool->child)        apr_pool_destroy(pool->child);    /* Run cleanups */    run_cleanups(&pool->cleanups);    /* Free subprocesses */    free_proc_chain(pool->subprocesses);    /* Remove the pool from the parents child list */    if (pool->parent) {#if APR_HAS_THREADS        apr_thread_mutex_t *mutex;        if ((mutex = apr_allocator_mutex_get(pool->parent->allocator)) != 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 */    }    /* Find the block attached to the pool structure.  Save a copy of the     * allocator pointer, because the pool struct soon will be no more.     */    allocator = pool->allocator;    active = pool->self;    *active->ref = NULL;#if APR_HAS_THREADS    if (apr_allocator_owner_get(allocator) == pool) {        /* Make sure to remove the lock, since it is highly likely to         * be invalid now.         */        apr_allocator_mutex_set(allocator, NULL);    }#endif /* APR_HAS_THREADS */    /* Free all the nodes in the pool (including the node holding the     * pool struct), by giving them back to the allocator.     */    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 (apr_allocator_owner_get(allocator) == pool) {        apr_allocator_destroy(allocator);    }}APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool,                                             apr_pool_t *parent,                                             apr_abortfunc_t abort_fn,                                             apr_allocator_t *allocator){    apr_pool_t *pool;    apr_memnode_t *node;    *newpool = NULL;    if (!parent)        parent = global_pool;    if (!abort_fn && parent)        abort_fn = parent->abort_fn;    if (allocator == NULL)        allocator = parent->allocator;    if ((node = allocator_alloc(allocator,                                MIN_ALLOC - APR_MEMNODE_T_SIZE)) == NULL) {        if (abort_fn)            abort_fn(APR_ENOMEM);        return APR_ENOMEM;    }    node->next = node;    node->ref = &node->next;    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->free_cleanups = NULL;    pool->subprocesses = NULL;    pool->user_data = NULL;    pool->tag = NULL;#ifdef NETWARE    pool->owner_proc = (apr_os_proc_t)getnlmhandle();#endif /* defined(NETWARE) */    if ((pool->parent = parent) != NULL) {#if APR_HAS_THREADS        apr_thread_mutex_t *mutex;        if ((mutex = apr_allocator_mutex_get(parent->allocator)) != NULL)            apr_thread_mutex_lock(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 (mutex)            apr_thread_mutex_unlock(mutex);#endif /* APR_HAS_THREADS */    }    else {        pool->sibling = NULL;        pool->ref = NULL;    }    *newpool = pool;    return APR_SUCCESS;}/* * "Print" functions *//* * apr_psprintf is implemented by writing directly into the current * block of the pool, starting right at first_avail.  If there's * insufficient room, then a new block is allocated and the earlier * output is copied over.  The new block isn't linked into the pool * until all the output is done. * * Note that this is completely safe because nothing else can * allocate in this apr_pool_t while apr_psprintf is running.  alarms are * blocked, and the only thing outside of apr_pools.c that's invoked * is apr_vformatter -- which was purposefully written to be * self-contained with no callouts. */struct psprintf_data {    apr_vformatter_buff_t vbuff;    apr_memnode_t   *node;    apr_pool_t      *pool;    apr_byte_t       got_a_new_node;    apr_memnode_t   *free;};#define APR_PSPRINTF_MIN_STRINGSIZE 32static int psprintf_flush(apr_vformatter_buff_t *vbuff){    struct psprintf_data *ps = (struct psprintf_data *)vbuff;    apr_memnode_t *node, *active;    apr_size_t cur_len, size;    char *strp;    apr_pool_t *pool;    apr_size_t free_index;    pool = ps->pool;    active = ps->node;    strp = ps->vbuff.curpos;    cur_len = strp - active->first_avail;    size = cur_len << 1;    /* Make sure that we don't try to use a block that has less     * than APR_PSPRINTF_MIN_STRINGSIZE bytes left in it.  This     * also catches the case where size == 0, which would result     * in reusing a block that can't even hold the NUL byte.     */    if (size < APR_PSPRINTF_MIN_STRINGSIZE)        size = APR_PSPRINTF_MIN_STRINGSIZE;    node = active->next;    if (!ps->got_a_new_node        && size < (apr_size_t)(node->endp - node->first_avail)) {        list_remove(node);        list_insert(node, active);        node->free_index = 0;        pool->active = node;        free_index = (APR_ALIGN(active->endp - active->first_avail + 1,                                BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;        active->free_index = (APR_UINT32_TRUNC_CAST)free_index;        node = active->next;        if (free_index < node->free_index) {            do {                node = node->next;            }            while (free_index < node->free_index);            list_remove(active);            list_insert(active, node);        }        node = pool->active;    }    else {        if ((node = allocator_alloc(pool->allocator, size)) == NULL)            return -1;        if (ps->got_a_new_node) {            active->next = ps->free;            ps->free = active;        }        ps->got_a_new_node = 1;    }    memcpy(node->first_avail, active->first_avail, cur_len);    ps->node = node;    ps->vbuff.curpos = node->first_avail + cur_len;    ps->vbuff.endpos = node->endp - 1; /* Save a byte for NUL terminator */    return 0;}APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap){    struct psprintf_data ps;    char *strp;    apr_size_t size;    apr_memnode_t *active, *node;    apr_size_t free_index;    ps.node = active = pool->active;    ps.pool = pool;    ps.vbuff.curpos  = ps.node->first_avail;    /* Save a byte for the NUL terminator */    ps.vbuff.endpos = ps.node->endp - 1;    ps.got_a_new_node = 0;    ps.free = NULL;    /* Make sure that the first node passed to apr_vformatter has at least     * room to hold the NUL terminator.     */    if (ps.node->first_avail == ps.node->endp) {        if (psprintf_flush(&ps.vbuff) == -1) {            if (pool->abort_fn) {                pool->abort_fn(APR_ENOMEM);            }            return NULL;        }    }    if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1) {        if (pool->abort_fn)            pool->abort_fn(APR_ENOMEM);        return NULL;    }    strp = ps.vbuff.curpos;    *strp++ = '\0';    size = strp - ps.node->first_avail;    size = APR_ALIGN_DEFAULT(size);    strp = ps.node->first_avail;    ps.node->first_avail += size;    if (ps.free)        allocator_free(pool->allocator, ps.free);    /*     * Link the node in if it's a new one     */    if (!ps.got_a_new_node)        return strp;    active = pool->active;    node = ps.node;    node->free_index = 0;    list_insert(node, active);    pool->active = node;    free_index = (APR_ALIGN(active->endp - active->first_avail + 1,                            BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;    active->free_index = (APR_UINT32_TRUNC_CAST)free_index;    node = active->next;    if (free_index >= node->free_index)        return strp;    do {        node = node->next;    }    while (free_index < node->free_index);    list_remove(active);    list_insert(active, node);    return strp;}#else /* APR_POOL_DEBUG *//* * Debug helper functions *//* * Walk the pool tree rooted at pool, depth first.  When fn returns * anything other than 0, abort the traversal and return the value * returned by fn. */static int apr_pool_walk_tree(apr_pool_t *pool,                              int (*fn)(apr_pool_t *pool, void *data),                              void *data){    int rv;    apr_pool_t *child;    rv = fn(pool, data);    if (rv)        return rv;#if APR_HAS_THREADS    if (pool->mutex) {        apr_thread_mutex_lock(pool->mutex);                        }#endif /* APR_HAS_THREADS */    child = pool->child;    while (child) {        rv = apr_pool_walk_tree(child, fn, data);        if (rv)            break;        child = child->sibling;    }#if APR_HAS_THREADS    if (pool->mutex) {        apr_thread_mutex_unlock(pool->mutex);    }#endif /* APR_HAS_THREADS */    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 (file_stderr) {        if (deref) {            apr_file_printf(file_stderr,                "POOL DEBUG: "                "[%lu"#if APR_HAS_THREADS                "/%lu"#endif /* APR_HAS_THREADS */                "] "                "%7s "                "(%10lu/%10lu/%10lu) "                "0x%08X \"%s\" "                "<%s> "                "(%u/%u/%u) "                "\n",                (unsigned long)getpid(),#if APR_HAS_THREADS                (unsigned long)apr_os_thread_current(),#endif /* APR_HAS_THREADS */                event,                (unsigned long)apr_pool_num_bytes(pool, 0),                (unsigned long)apr_pool_num_bytes(pool, 1),                (unsigned long)apr_pool_num_bytes(global_pool, 1),                (unsigned int)pool, pool->tag,                file_line,                pool->stat_alloc, pool->stat_total_alloc, pool->stat_clear);        }        else {            apr_file_printf(file_stderr,                "POOL DEBUG: "                "[%lu"#if APR_HAS_THREADS                "/%lu"#endif /* APR_HAS_THREADS */                "] "                "%7s "                "                                   "                "0x%08X "                "<%s> "                "\n",                (unsigned long)getpid(),#if APR_HAS_THREADS                (unsigned long)apr_os_thread_current(),#endif /* APR_HAS_THREADS */                event,                (unsigned int)pool,                file_line);        }    }}#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */#if (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME)

⌨️ 快捷键说明

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