nginx菜鸟模块开发遇到的问题汇总之nginx_array_t
关于ngx_array_t结构体的定义和操作函数都在ngx_array.h/ngx_array.c文件中
1 struct ngx_array_s { 2 void *elts; //数组数据区起始位置 3 ngx_uint_t nelts; //实际存放的元素个数 4 size_t size; //每个元素大小 5 ngx_uint_t nalloc; //数组所含的空间个数,即可容纳的最大的原书数目 6 ngx_pool_t *pool; //该数组在内存池中的分配 7 };
数组操作共有5个::
1 ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size); //创建ngx_array 2 void ngx_array_destroy(ngx_array_t *a); //删除或回收 3 void *ngx_array_push(ngx_array_t *a); //向数组添加元素 4 void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n); //向数组添加n个元素 5 static ngx_inline ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size);//初始化数组
ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
{
从存储池p中,分配n*size的空间;
etls指向了分配空间的首地址;
初始化ngx_array_t相关元素:
nelts = 0;//没有元素,或者也可以理解为,当前可以使用数组空间的下标
a - > size =size;元素size
nalloc = n ;数组可容纳元素的个数
pool = p;数组所在的存储池
}
ngx_array_init与ngx_array_create不同之处在,init不需要为ngx_array_t本身分配空间。
void * ngx_array_push(ngx_array_t *a);
从数组a中取一个元素的空间,将元素空间地址返回;
如果数组已经满了,则继续从数组a的内存池中分配存储空间,这里分为两种情况:
1. 如果数组位于内存池的尾部,则继续分配一个元素的空间,返回;//这是因为能够保证新分配的元素与原始的数组空间是连续的
2. 如果数组不是位于内存池尾部,则重新分配2倍的存储空间,将原来的数组元素拷贝到新的分配空间中


ngx_array_push_n处理过程与ngx_array_push类似,不同之处仅在于需要分配连续n个数组元素的空间;
ngx_array_destroy回收数组a的空间,仅当数组位于p的尾部时才会回收;//ngx_pool的具体回收机制,需要研读相关代码部分才可知。
1 void ngx_array_destroy(ngx_array_t *a) 2 { 3 ngx_pool_t *p; 4 5 p = a->pool; 6 7 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) { 8 p->d.last -= a->size * a->nalloc; 9 } 10 11 if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) { 12 p->d.last = (u_char *) a; 13 } 14 }