nginx数据结构(ngx_pool_t)

ngx_pool_t是一个非常重要的数据结构,在很多重要的场合都有使用,很多重要的数据结构也都在使用它。那么它究竟是一个什么东西呢?简单的说,它提供了一种机制,帮助管理一系列的资源(如内存,文件等),使得对这些资源的使用和释放统一进行,免除了使用过程中考虑到对各种各样资源的什么时候释放,是否遗漏了释放的担心。

typedef struct ngx_pool_s ngx_pool_t;

struct ngx_pool_s {
    ngx_pool_data_t       d;
    size_t                max;
    ngx_pool_t           *current;
    ngx_chain_t          *chain;
    ngx_pool_large_t     *large;
    ngx_pool_cleanup_t   *cleanup;
    ngx_log_t            *log;
};

struct ngx_pool_large_s {
    ngx_pool_large_t     *next;
    void                 *alloc;
};

typedef struct {
    u_char               *last;
    u_char               *end;
    ngx_pool_t           *next;
    ngx_uint_t            failed;
} ngx_pool_data_t;

/*创建一个初始节点大小为size的pool,log为后续在该pool上进行操作时输出日志的对象。
需要说明的是size的选择,size的大小必须小于等于NGX_MAX_ALLOC_FROM_POOL,且必须大于sizeof(ngx_pool_t)。
选择大于NGX_MAX_ALLOC_FROM_POOL的值会造成浪费,因为大于该限制的空间不会被用到
(只是说在第一个由ngx_pool_t对象管理的内存块上的内存,后续的分配如果第一个内存块上的空闲部分已用完,会再分配的)。*/
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);

/*从这个pool中分配一块为size大小的内存。
注意,此函数分配的内存的起始地址按照NGX_ALIGNMENT进行了对齐。对齐操作会提高系统处理的速度,但会造成少量内存的浪费。*/
void *ngx_palloc(ngx_pool_t *pool, size_t size);

/*从这个pool中分配一块为size大小的内存。但是此函数分配的内存并没有像上面的函数那样进行过对齐。*/
void *ngx_pnalloc(ngx_pool_t *pool, size_t size);

/*该函数也是分配size大小的内存,并且对分配的内存块进行了清零。内部实际上是转调用ngx_palloc实现的。*/
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);

/*按照指定对齐大小alignment来申请一块大小为size的内存。此处获取的内存不管大小都将被置于大内存块链中管理。*/
void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);

/*对于被置于大块内存链,也就是被large字段管理的一列内存中的某块进行释放。
该函数的实现是顺序遍历large管理的大块内存链表。所以效率比较低下。
如果在这个链表中找到了这块内存,则释放,并返回NGX_OK。否则返回NGX_DECLINED。*/
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);

/*ngx_pool_t中的cleanup字段管理着一个特殊的链表,该链表的每一项都记录着一个特殊的需要释放的资源。
对于这个链表中每个节点所包含的资源如何去释放,是自说明的。*/
ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);
typedef struct ngx_pool_cleanup_s  ngx_pool_cleanup_t;
typedef void (*ngx_pool_cleanup_pt)(void *data);
struct ngx_pool_cleanup_s {
    ngx_pool_cleanup_pt   handler;//是一个函数指针,指向一个可以释放data所对应资源的函数。该函数只有一个参数,就是data
    void                 *data;//指明了该节点所对应的资源。
    ngx_pool_cleanup_t   *next;//指向该链表中下一个元素。
};
/*该函数就是释放pool中持有的所有内存,
以及依次调用cleanup字段所管理的链表中每个元素的handler字段所指向的函数,
来释放掉所有该pool管理的资源。并且把pool指向的ngx_pool_t也释放掉了,完全不可用了。*/
void ngx_destroy_pool(ngx_pool_t *pool);
/*该函数释放pool中所有大块内存链表上的内存,小块内存链上的内存块都修改为可用。但是不会去处理cleanup链表上的项目。*/
void ngx_reset_pool(ngx_pool_t *pool);




ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log)
{
    ngx_pool_t  *p;

    p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
    if (p == NULL) {
        return NULL;
    }

    p->d.last = (u_char *) p + sizeof(ngx_pool_t);
    p->d.end = (u_char *) p + size;
    p->d.next = NULL;
    p->d.failed = 0;

    size = size - sizeof(ngx_pool_t);
    p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;

    p->current = p;
    p->chain = NULL;
    p->large = NULL;
    p->cleanup = NULL;
    p->log = log;

    return p;
}

void * ngx_palloc(ngx_pool_t *pool, size_t size)
{
    u_char      *m;
    ngx_pool_t  *p;
    
    if (size <= pool->max) {
        p = pool->current;
        do {
            m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
            if ((size_t) (p->d.end - m) >= size) {
                p->d.last = m + size;   
                return m;
            }
            p = p->d.next;
        } while (p);
        return ngx_palloc_block(pool, size);
    }
    return ngx_palloc_large(pool, size);
}


void * ngx_pnalloc(ngx_pool_t *pool, size_t size)
{
    u_char      *m;
    ngx_pool_t  *p;
    
    if (size <= pool->max) {
        p = pool->current;
        do {
            m = p->d.last;
            if ((size_t) (p->d.end - m) >= size) {
                p->d.last = m + size;
                return m;
            }
            p = p->d.next;
        } while (p);
        return ngx_palloc_block(pool, size);
    }
    return ngx_palloc_large(pool, size);
}


void * ngx_pcalloc(ngx_pool_t *pool, size_t size)
{
    void *p;
    
    p = ngx_palloc(pool, size);
    if (p) {
        ngx_memzero(p, size);
    }
    return p;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值