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

📄 apr_pools.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ==================================================================== * 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 * <http://www.apache.org/>. *//* * Resource allocation code... the code here is responsible for making * sure that nothing leaks. * * rst --- 4/95 --- 6/95 */#include "apr.h"#include "apr_private.h"#include "apr_portable.h" /* for get_os_proc */#include "apr_strings.h"#include "apr_general.h"#include "apr_pools.h"#include "apr_lib.h"#include "apr_lock.h"#include "apr_hash.h"#if APR_HAVE_STDIO_H#include <stdio.h>#endif#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif#if APR_HAVE_SYS_SIGNAL_H#include <sys/signal.h>#endif#if APR_HAVE_SIGNAL_H#include <signal.h>#endif#if APR_HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#if APR_HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if APR_HAVE_UNISTD_H#include <unistd.h>#endif#if APR_HAVE_FCNTL_H#include <fcntl.h>#endif#if APR_HAVE_STRING_H#include <string.h>#endif#if APR_HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_MALLOC_H#include <malloc.h>#endif/* Details of the debugging options can now be found in the developer * section of the documentaion. *//* magic numbers --- min free bytes to consider a free apr_pool_t block useable, * and the min amount to allocate if we have to go to malloc() */#ifndef BLOCK_MINFREE#define BLOCK_MINFREE 4096#endif#ifndef BLOCK_MINALLOC#define BLOCK_MINALLOC 8192#endif #ifdef APR_POOL_DEBUG/* first do some option checking... */#ifdef ALLOC_USE_MALLOC#error "sorry, no support for ALLOC_USE_MALLOC and APR_POOL_DEBUG at the same time"#endif /* ALLOC_USE_MALLOC */#ifdef MULTITHREAD# error "sorry, no support for MULTITHREAD and APR_POOL_DEBUG at the same time"#endif /* MULTITHREAD */#endif /* APR_POOL_DEBUG */#ifdef ALLOC_USE_MALLOC#undef BLOCK_MINFREE#undef BLOCK_MINALLOC#define BLOCK_MINFREE	0#define BLOCK_MINALLOC	0#endif /* ALLOC_USE_MALLOC */#define APR_SLACK_LOW    1#define APR_SLACK_HIGH   2/***************************************************************** * * Managing free storage blocks... */union align {    /*     * Types which are likely to have the longest RELEVANT alignment     * restrictions...     */    char *cp;    void (*f) (void);    long l;    FILE *fp;    double d;};#define CLICK_SZ (sizeof(union align))union block_hdr {    union align a;    /* Actual header... */    struct {	char *endp;	union block_hdr *next;	char *first_avail;#ifdef APR_POOL_DEBUG	union block_hdr *global_next;	apr_pool_t *owning_pool;#endif /* APR_POOL_DEBUG */    } h;};#define APR_ABORT(conditional, retcode, func, str) \    if (conditional) { \        if ((func) == NULL) { \            return NULL; \        } \        else { \            fprintf(stderr, "%s", str); \            (*(func))(retcode); \        } \    }/* * Static cells for managing our internal synchronisation. */static union block_hdr *block_freelist = NULL;#if APR_HAS_THREADSstatic apr_lock_t *alloc_mutex;static apr_lock_t *spawn_mutex;#endif#ifdef APR_POOL_DEBUGstatic char *known_stack_point;static int stack_direction;static union block_hdr *global_block_list;#define FREE_POOL	((apr_pool_t *)(-1))#endif /* APR_POOL_DEBUG */#ifdef ALLOC_STATSstatic unsigned long long num_free_blocks_calls;static unsigned long long num_blocks_freed;static unsigned max_blocks_in_one_free;static unsigned num_malloc_calls;static unsigned num_malloc_bytes;#endif /* ALLOC_STATS */#ifdef ALLOC_DEBUG#define FILL_BYTE	((char)(0xa5))#define debug_fill(ptr,size)	((void)memset((ptr), FILL_BYTE, (size)))static APR_INLINE void debug_verify_filled(const char *ptr, const char *endp,					   const char *error_msg){    for ( ; ptr < endp; ++ptr) {	if (*ptr != FILL_BYTE) {	    fputs(error_msg, stderr);	    abort();	    exit(1);	}    }}#else /* ALLOC_DEBUG */#define debug_fill(a,b)#define debug_verify_filled(a,b,c)#endif /* ALLOC_DEBUG *//* * Get a completely new block from the system pool. Note that we rely on * malloc() to provide aligned memory. */static union block_hdr *malloc_block(int size, int (*apr_abort)(int retcode)){    union block_hdr *blok;#ifdef ALLOC_DEBUG    /* make some room at the end which we'll fill and expect to be     * always filled     */    size += CLICK_SZ;#endif /* ALLOC_DEBUG */#ifdef ALLOC_STATS    ++num_malloc_calls;    num_malloc_bytes += size + sizeof(union block_hdr);#endif /* ALLOC_STATS */    blok = (union block_hdr *) malloc(size + sizeof(union block_hdr));    APR_ABORT(blok == NULL, APR_ENOMEM, apr_abort,              "Ouch!  malloc failed in malloc_block()\n");    debug_fill(blok, size + sizeof(union block_hdr));    blok->h.next = NULL;    blok->h.first_avail = (char *) (blok + 1);    blok->h.endp = size + blok->h.first_avail;#ifdef ALLOC_DEBUG    blok->h.endp -= CLICK_SZ;#endif /* ALLOC_DEBUG */#ifdef APR_POOL_DEBUG    blok->h.global_next = global_block_list;    global_block_list = blok;    blok->h.owning_pool = NULL;#endif /* APR_POOL_DEBUG */    return blok;}#if defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC)static void chk_on_blk_list(union block_hdr *blok, union block_hdr *free_blk){    debug_verify_filled(blok->h.endp, blok->h.endp + CLICK_SZ,			"[chk_on_blk_list] Ouch!  Someone trounced the padding "			"at the end of a block!\n");    while (free_blk) {	if (free_blk == blok) {            fprintf(stderr, "Ouch!  Freeing free block\n");	    abort();	    exit(1);	}	free_blk = free_blk->h.next;    }}#else /* defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC) */#define chk_on_blk_list(_x, _y)#endif /* defined(ALLOC_DEBUG) && !defined(ALLOC_USE_MALLOC) *//* Free a chain of blocks --- must be called with alarms blocked. */static void free_blocks(union block_hdr *blok){#ifdef ALLOC_USE_MALLOC    union block_hdr *next;    for ( ; blok; blok = next) {	next = blok->h.next;	free(blok);    }#else /* ALLOC_USE_MALLOC */#ifdef ALLOC_STATS    unsigned num_blocks;#endif /* ALLOC_STATS */    /*     * First, put new blocks at the head of the free list ---     * we'll eventually bash the 'next' pointer of the last block     * in the chain to point to the free blocks we already had.     */    union block_hdr *old_free_list;    if (blok == NULL) {	return;			/* Sanity check --- freeing empty pool? */    }#if APR_HAS_THREADS    if (alloc_mutex) {        apr_lock_acquire(alloc_mutex);    }#endif    old_free_list = block_freelist;    block_freelist = blok;    /*     * Next, adjust first_avail pointers of each block --- have to do it     * sooner or later, and it simplifies the search in new_block to do it     * now.     */#ifdef ALLOC_STATS    num_blocks = 1;#endif /* ALLOC_STATS */    while (blok->h.next != NULL) {#ifdef ALLOC_STATS	++num_blocks;#endif /* ALLOC_STATS */	chk_on_blk_list(blok, old_free_list);	blok->h.first_avail = (char *) (blok + 1);	debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);#ifdef APR_POOL_DEBUG 	blok->h.owning_pool = FREE_POOL;#endif /* APR_POOL_DEBUG */	blok = blok->h.next;    }    chk_on_blk_list(blok, old_free_list);    blok->h.first_avail = (char *) (blok + 1);    debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);#ifdef APR_POOL_DEBUG    blok->h.owning_pool = FREE_POOL;#endif /* APR_POOL_DEBUG */    /* Finally, reset next pointer to get the old free blocks back */    blok->h.next = old_free_list;#ifdef ALLOC_STATS    if (num_blocks > max_blocks_in_one_free) {	max_blocks_in_one_free = num_blocks;    }    ++num_free_blocks_calls;    num_blocks_freed += num_blocks;#endif /* ALLOC_STATS */#if APR_HAS_THREADS    if (alloc_mutex) {        apr_lock_release(alloc_mutex);    }#endif /* APR_HAS_THREADS */#endif /* ALLOC_USE_MALLOC */}/* * Get a new block, from our own free list if possible, from the system * if necessary.  Must be called with alarms blocked. */static union block_hdr *new_block(int min_size, int (*apr_abort)(int retcode)){    union block_hdr **lastptr = &block_freelist;    union block_hdr *blok = block_freelist;    /* First, see if we have anything of the required size     * on the free list...     */    while (blok != NULL) {	if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {	    *lastptr = blok->h.next;	    blok->h.next = NULL;	    debug_verify_filled(blok->h.first_avail, blok->h.endp,				"[new_block] Ouch!  Someone trounced a block "				"on the free list!\n");	    return blok;	}	else {	    lastptr = &blok->h.next;	    blok = blok->h.next;	}    }    /* Nope. */    min_size += BLOCK_MINFREE;    blok = malloc_block((min_size > BLOCK_MINALLOC)			? min_size : BLOCK_MINALLOC, apr_abort);    return blok;}/* Accounting */static apr_size_t bytes_in_block_list(union block_hdr *blok){    apr_size_t size = 0;    while (blok) {

⌨️ 快捷键说明

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