nginx的结构

nginx的核心数据结构

typedef struct ngx_module_s          ngx_module_t;
typedef struct ngx_conf_s            ngx_conf_t;
typedef struct ngx_cycle_s           ngx_cycle_t;
typedef struct ngx_pool_s            ngx_pool_t;
typedef struct ngx_chain_s           ngx_chain_t;
typedef struct ngx_log_s             ngx_log_t;
typedef struct ngx_open_file_s       ngx_open_file_t;
typedef struct ngx_command_s         ngx_command_t;
typedef struct ngx_file_s            ngx_file_t;
typedef struct ngx_event_s           ngx_event_t;
typedef struct ngx_event_aio_s       ngx_event_aio_t;
typedef struct ngx_connection_s      ngx_connection_t;
typedef struct ngx_thread_task_s     ngx_thread_task_t;
typedef struct ngx_ssl_s             ngx_ssl_t;
typedef struct ngx_ssl_connection_s  ngx_ssl_connection_t;

数组

ngx_array_t结构

typedef struct {
    void        *elts;  '实际的数据存储区起始地址'
    ngx_uint_t   nelts; '数组实际元素个数'
    size_t       size;  '数组单个元素的大小,单位是字节'
    ngx_uint_t   nalloc;    '数组的容量:表示该数组在不引起扩容的前提下,能够最多存储的元素的个数'
    ngx_pool_t  *pool;  '该数组结构,分配的的内存在内存池中的位置'
} ngx_array_t;
  • 特色:nginx

    • 当nelts增加到达nalloc 时,若是再往此数组中存储元素,则会引起数组的扩容。数组的容量将会扩展到原有容量的2倍大小。其实是分配新的一块内存,新的一块内存的大小是原有内存大小的2倍。原有的数据会被拷贝到新的一块内存中。

输入图片说明

函数

ngx_array_init:数组初始化
/**
    
*/

static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    /*
     * set "array->nelts" before "array->elts", otherwise MSVC thinks
     * that "array->nelts" may be used without having been initialized
     */

    array->nelts = 0;
    array->size = size;
    array->nalloc = n;
    array->pool = pool;

    array->elts = ngx_palloc(pool, n * size);   'n个数组数据地址,在内存池中的位置'
    if (array->elts  NULL) {
        return NGX_ERROR;
    }

    return NGX_OK;
}
  • 特色:初始化n*size大小的内存池,并链接到 *array上,
初始化:ngx_array_create:建立
/**
    先在内存池中分配一个数组头,而后在分配 n*size 大小的内存
    ngx_pool_t:内存池
    ngx_uint_t:数组大小
*/
ngx_array_t *
ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
{
    ngx_array_t *a;

    a = ngx_palloc(p, sizeof(ngx_array_t)); '初始化一个数组大小的内存池,做为数组的引用'
    if (a  NULL) {
        return NULL;
    }

    if (ngx_array_init(a, p, n, size) != NGX_OK) {  '初始化n个数组内存空间,存储数组'
        return NULL;
    }

    return a;
}
销毁一个数组空间:ngx_array_destroy
void
ngx_array_destroy(ngx_array_t *a)
{
    ngx_pool_t  *p;

    p = a->pool;

    if ((u_char *) a->elts + a->size * a->nalloc  p->d.last) {    '若是数组满'
        p->d.last -= a->size * a->nalloc;   '清理全部数组'
    }

    if ((u_char *) a + sizeof(ngx_array_t)  p->d.last) {
        p->d.last = (u_char *) a;
    }
}
获取下一个成员的其实地址:ngx_array_push
  • 特色:c++

    • 若是数组满:
      • nalloc=1且这个内存池中没有人使用,直接分配一个
      • 扩容成2倍大小
    • 直接获取下一个数的起始地址。
void *
ngx_array_push(ngx_array_t *a)
{
    void        *elt, *new;
    size_t       size;
    ngx_pool_t  *p;

    if (a->nelts  a->nalloc) {

        /* the array is full */

        size = a->size * a->nalloc;

        p = a->pool;
        // 数组才个数=1
        // 未分配空间>已使用空间+size 
        if ((u_char *) a->elts + size  p->d.last
            && p->d.last + a->size <= p->d.end)
        {
            /*
             * the array allocation is the last in the pool
             * and there is space for new allocation
             */
            //容量+1
            p->d.last += a->size;
            a->nalloc++;

        } else {
            /* allocate a new array */
            // 容量*2
            new = ngx_palloc(p, 2 * size);
            if (new  NULL) {
                return NULL;
            }

            ngx_memcpy(new, a->elts, size);
            a->elts = new;
            a->nalloc *= 2;
        }
    }
    //数字其实地址+个数*size
    elt = (u_char *) a->elts + a->size * a->nelts;  //下一个数的起始地址
    a->nelts++; //个数+1

    return elt;
}
  • 特色:数组

    • (u_char *) a->elts + size p->d.last && p->d.last + a->size <= p->d.end
      • 未分配空间>一个数组值的大小
      • 数组值起始位置+一个数组值的大小=未分配空间起始地址
压入(存入)个数:ngx_array_push_n
void *
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
{
    void        *elt, *new;
    size_t       size;
    ngx_uint_t   nalloc;
    ngx_pool_t  *p;

    size = n * a->size;

    if (a->nelts + n > a->nalloc) {

        /* the array is full */

        p = a->pool;

        if ((u_char *) a->elts + a->size * a->nalloc  p->d.last
            && p->d.last + size <= p->d.end)
        {
            /*
             * the array allocation is the last in the pool
             * and there is space for new allocation
             */

            p->d.last += size;
            a->nalloc += n;

        } else {
            /* allocate a new array */

            nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);

            new = ngx_palloc(p, nalloc * a->size);
            if (new  NULL) {
                return NULL;
            }

            ngx_memcpy(new, a->elts, a->nelts * a->size);
            a->elts = new;
            a->nalloc = nalloc;
        }
    }

    elt = (u_char *) a->elts + a->size * a->nelts;
    a->nelts += n;

    return elt;
}

ngx_list_t:列表

输入图片说明

//链接头
typedef struct {
    ngx_list_part_t  *last; '指向链表中最后一个ngx_list_part_t,用于管理整个链表,含义很明确'
    ngx_list_part_t   part; '链表第一个节点,表示一块连续的内存空间。'
    size_t            size; '链表中每一个节点中存放元素大小'
    ngx_uint_t        nalloc;   '链表中每一个节点能够存放的元素个数。'
    ngx_pool_t       *pool; '链表使用的内存池。'
} ngx_list_t;

//链接表
struct ngx_list_part_s {
    void             *elts; '链表节点使用的内存块地址'
    ngx_uint_t        nelts;    '当前链表节点已经存放的元素个数'
    ngx_list_part_t  *next; '指向链表的下一个节点'
};
建立和初始化:ngx_list_create、ngx_list_init
//建立链表引用
ngx_list_t *
ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    ngx_list_t  *list;

    list = ngx_palloc(pool, sizeof(ngx_list_t));
    if (list  NULL) {
        return NULL;
    }

    if (ngx_list_init(list, pool, n, size) != NGX_OK) {
        return NULL;
    }

    return list;
}
//初始化
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    list->part.elts = ngx_palloc(pool, n * size);
    if (list->part.elts  NULL) {
        return NGX_ERROR;
    }

    list->part.nelts = 0;
    list->part.next = NULL;
    list->last = &list->part;
    list->size = size;
    list->nalloc = n;
    list->pool = pool;

    return NGX_OK;
}
相关文章
相关标签/搜索