Nginx-ngx_buf

来源:互联网 发布:淘宝小恶魔药妆假货 编辑:程序博客网 时间:2024/06/06 17:47

    Nginx中关于缓冲区的相关操作全部在ngx_buf这个源代码文件里, 先来看看buf涉及到的数据结构。

typedef void *            ngx_buf_tag_t;typedef struct ngx_buf_s  ngx_buf_t;struct ngx_buf_s {    u_char          *pos;    u_char          *last; //buffer当前使用到的位置    off_t            file_pos;    off_t            file_last;    u_char          *start;         /* start of buffer */    u_char          *end;           /* end of buffer */    ngx_buf_tag_t    tag;    ngx_file_t      *file;    ngx_buf_t       *shadow;    /* the buf's content could be changed */    unsigned         temporary:1;    /*       * the buf's content is in a memory cache or in a read only memory     * and must not be changed     */    unsigned         memory:1; /* the buf's content is mmap()ed and must not be changed */    unsigned         mmap:1;    unsigned         recycled:1;    unsigned         in_file:1;    unsigned         flush:1;    unsigned         sync:1;    unsigned         last_buf:1;    unsigned         last_in_chain:1;    unsigned         last_shadow:1;    unsigned         temp_file:1;    /* STUB */ int   num;};struct ngx_chain_s {    ngx_buf_t    *buf;    ngx_chain_t  *next;};
在ngx_buf_t中涉及到多个位域,基本都是用于标志位,这里先不做详细的解释。 先来看看基本基本的函数。

ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size){    ngx_buf_t *b;     //#define ngx_calloc_buf(pool) ngx_pcalloc(pool, sizeof(ngx_buf_t))    b = ngx_calloc_buf(pool);    if (b == NULL) {        return NULL;    }       //初始化buf的起始指针,为buf申请空降    b->start = ngx_palloc(pool, size);    if (b->start == NULL) {        return NULL;    }       /*       * set by ngx_calloc_buf():     *     *     b->file_pos = 0;     *     b->file_last = 0;     *     b->file = NULL;     *     b->shadow = NULL;     *     b->tag = 0;     *     and flags     */    b->pos = b->start;    b->last = b->start;    b->end = b->last + size;      b->temporary = 1;    return b;}
再来看下关于创建buffer链表的接口函数
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs){    u_char       *p;    ngx_int_t     i;    ngx_buf_t    *b;    ngx_chain_t  *chain, *cl, **ll;    //申请链表所需要的总空间    p = ngx_palloc(pool, bufs->num * bufs->size);    if (p == NULL) {        return NULL;    }    ll = &chain;    //逐个处理各个buf,主要是初始化和建立链表    for (i = 0; i < bufs->num; i++) {        //buf本身需要的空间申请        b = ngx_calloc_buf(pool);        if (b == NULL) {            return NULL;        }  /*         * set by ngx_calloc_buf():         *         *     b->file_pos = 0;         *     b->file_last = 0;         *     b->file = NULL;         *     b->shadow = NULL;         *     b->tag = 0;         *     and flags         *         */        b->pos = p;        b->last = p;        b->temporary = 1;        //buffer数据区指针初始化        b->start = p;        p += bufs->size;        b->end = p;        //从pool中申请一个ngx_chain_t节点的空间        cl = ngx_alloc_chain_link(pool);        if (cl == NULL) {            return NULL;        }        cl->buf = b;        *ll = cl;        ll = &cl->next;        }    *ll = NULL;    //最后返回链表的头节点。    return chain;}                
上面这个函数里用到了 ngx_alloc_chain_link这函数,这个函数的主要功能是从pool中申请一个ngx_chain_t的结构体空间。

ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool){    ngx_chain_t  *cl;    cl = pool->chain;    //当pool中有chain节点的时候,直接拿出来用,就不需要重新申请了。    if (cl) {        pool->chain = cl->next;        return cl;    }    //pool中的chain节点用完了,那么需要从pool中重新申请    cl = ngx_palloc(pool, sizeof(ngx_chain_t));    if (cl == NULL) {        return NULL;    }    return cl;}

实际上这个函数就是从pool中的chain链表中去拿节点,没有了那么需要从内存池子中去申请。

对应于上一个申请空间的函数,那么还有一个回收空间的函数,不过这里是采用宏定义的方式实现的:

#define ngx_free_chain(pool, cl)                                             \    cl->next = pool->chain;                                                  \    pool->chain = cl

这个回收过程很简单,直接将需要回收的节点加入到pool中链表头部就行了。


这个源代码中还有一些其他的数据结构和函数,这里先不分析了,因为还不太清楚或者猜测其用途,等真正遇到了再回头添加。







原创粉丝点击