ngx_list_init
定義在 src\core\ngx_list.h
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;
}
ngx_list_init
是 Nginx 中用于初始化鏈表結構的關鍵函數
函數簽名
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size
);
1. static ngx_inline
-
static
限制函數的作用域為當前編譯單元(即當前源文件),防止與其他文件中的同名函數沖突。 -
ngx_inline
Nginx 定義的宏(通常展開為inline
),提示編譯器將函數內聯展開,減少函數調用開銷。適用于頻繁調用的小函數(如初始化、簡單操作)。
2. 返回值 ngx_int_t
- 返回值含義:
NGX_OK
(成功):初始化成功,鏈表可用。NGX_ERROR
(失敗):內存分配失敗
3. 參數詳解
(1) ngx_list_t *list
- 類型:指向
ngx_list_t
結構的指針。 - 作用:需要被初始化的鏈表對象。
(2) ngx_pool_t *pool
- 類型:指向 Nginx 內存池的指針。
- 作用:為鏈表提供內存分配服務。
- 意義:
- 所有鏈表相關的內存(包括初始數據塊和后續擴展的數據塊)均從該內存池分配。
- 內存池管理簡化了內存釋放流程(銷毀池即可回收所有內存)。
(3) ngx_uint_t n
- 類型:Nginx 自定義的無符號整型(
typedef unsigned int ngx_uint_t
)。 - 作用:指定每個數據塊預分配的元素數量。
- 影響:
- 決定初始內存塊的大小為
n * size
。 - 值過大會浪費內存,過小會導致頻繁分配新數據塊。
- 決定初始內存塊的大小為
(4) size_t size
- 類型:標準庫的無符號整型(通常為
unsigned long
)。 - 作用:指定鏈表中每個元素的大小(字節)。
- 要求:
- 必須與實際存儲的數據類型大小一致(如
sizeof(ngx_table_elt_t)
)。
- 必須與實際存儲的數據類型大小一致(如
詳解
1. 分配初始內存塊
list->part.elts = ngx_palloc(pool, n * size);
為鏈表的第一個數據塊分配內存,大小為 n * size
。
ngx_palloc
從 pool
分配內存,返回指針賦給 part.elts
。
2. 檢查內存分配結果
if (list->part.elts == NULL) {return NGX_ERROR;
}
驗證內存分配是否成功。
內存分配失敗會導致后續操作崩潰,需立即返回錯誤。
若 elts
為 NULL
,說明分配失敗,返回 NGX_ERROR
。
3. 初始化當前塊元素計數
list->part.nelts = 0;
設置當前塊已用元素數量為 0。
nelts
(number of elements)記錄塊內已使用的元素數,初始時未添加元素。
提供計數功能,便于后續判斷是否需要分配新塊。
4. 初始化當前塊的后繼指針
list->part.next = NULL;
標記當前塊為最后一個塊,無后續塊。
鏈表初始僅包含一個塊,后續塊通過 next
指針鏈接。
5. 設置最后一個塊的指針
list->last = &list->part;
將 last
指向鏈表的第一個塊(即當前唯一塊)。
last
是指向鏈表最后一個塊的指針,用于快速追加元素。
&list->part
獲取第一個塊的地址,賦給 last
。
通過 last
直接定位到鏈表尾部,避免遍歷整個鏈表,提升插入效率。
6. 保存元素大小
list->size = size;
記錄每個元素的大小(字節)。
后續添加元素時需根據 size
計算內存偏移量。
7. 保存預分配元素數量
list->nalloc = n;
記錄每個塊預分配的元素數量。
新塊分配時需按 n
預分配內存,平衡內存使用與性能。
控制內存分配粒度,減少碎片化。
8. 關聯內存池
list->pool = pool;
保存內存池指針,用于后續內存分配。
9. 返回成功狀態
return NGX_OK;
通知調用者初始化成功。
明確函數執行結果,便于錯誤處理。