nginx很多数数据结构都在ngx_core.h 中定义了别名 以_t结尾。
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_proxy_protocol_s ngx_proxy_protocol_t;
typedef struct ngx_ssl_connection_s ngx_ssl_connection_t;
typedef struct ngx_udp_connection_s ngx_udp_connection_t;
1、ngx_array_t
ngx_array_t 在ngx_array.h 中定义,数组的添加和移除等操作 函数也在ngx_array.cpp 中实现。
typedef struct {
void *elts; //数组真实数据的首地址
ngx_uint_t nelts; //当前数组长度
size_t size; //数组中每个元素站的字节数 即elts指向的每个元素的数据长度
ngx_uint_t nalloc; //数组的最大长度
ngx_pool_t *pool; //内存池 使用poll来为elts分配内存
} ngx_array_t;
ngx_array_create()函数创建一个ngx_array_t结构的数组。为数组初始化成员变量。并且也会为elts分配内存。
ngx_array_push()向数组中添加一个元素。如果数组长度不够这个函数会重新申请内存。
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;
//size 等于数组总共的字节数(每个元素的字节数*元素个数)
p = a->pool;
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
*/
p->d.last += a->size; // 分配一个元素的空间给数组
a->nalloc++; //数组最大长度加一
} else {
//如果内存池已经没有空间了 那么就重新找内存池中有空间的块 重新分配内存 这次重新分配内存会是原来数组内存的两倍。
/* allocate a new array */
new = ngx_palloc(p, 2 * size); //从内存池中分配原数组内存的两倍空间
if (new == NULL) {
return NULL;
}
ngx_memcpy(new, a->elts, size); //将原数组中的数据拷贝到新内存中
a->elts = new;
a->nalloc *= 2; //数组的最大长度是原来的两倍
}
}
elt = (u_char *) a->elts + a->size * a->nelts;
a->nelts++; //数组当前长度加一
return elt; // 返回新添加元素的地址
}
2、ngx_pool_s
内存池结构
typedef struct {
u_char *last; //当前内存块已分配内存的尾地址 也是未分配内存的首地址
u_char *end; //当前内存块的尾地址
ngx_pool_t *next; //指向下一个内存块
ngx_uint_t failed; //记录分配失败次数
} ngx_pool_data_t;
struct ngx_pool_s {
ngx_pool_data_t d; //指向ngx_pool_data_t结构
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; //记录日志
};