Ubuntu 下 nginx-1.24.0 源码分析 - ngx_list_init

ngx_list_init


定义 在 src\core\ngx_list.h

c 复制代码
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 中用于初始化链表结构的关键函数


函数签名

c 复制代码
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. 分配初始内存块
c 复制代码
list->part.elts = ngx_palloc(pool, n * size);

为链表的第一个数据块分配内存,大小为 n * size。

ngx_palloc 从 pool 分配内存,返回指针赋给 part.elts。


2. 检查内存分配结果
c 复制代码
if (list->part.elts == NULL) {
    return NGX_ERROR;
}

验证内存分配是否成功。

内存分配失败会导致后续操作崩溃,需立即返回错误。

若 elts 为 NULL,说明分配失败,返回 NGX_ERROR。


3. 初始化当前块元素计数
c 复制代码
list->part.nelts = 0;

设置当前块已用元素数量为 0。

nelts(number of elements)记录块内已使用的元素数,初始时未添加元素。

提供计数功能,便于后续判断是否需要分配新块。


4. 初始化当前块的后继指针
c 复制代码
list->part.next = NULL;

标记当前块为最后一个块,无后续块。

链表初始仅包含一个块,后续块通过 next 指针链接。


5. 设置最后一个块的指针
c 复制代码
list->last = &list->part;

将 last 指向链表的第一个块(即当前唯一块)。

last 是指向链表最后一个块的指针,用于快速追加元素。

&list->part 获取第一个块的地址,赋给 last。

通过 last 直接定位到链表尾部,避免遍历整个链表,提升插入效率。


6. 保存元素大小
c 复制代码
list->size = size;

记录每个元素的大小(字节)。

后续添加元素时需根据 size 计算内存偏移量。


7. 保存预分配元素数量
c 复制代码
list->nalloc = n;

记录每个块预分配的元素数量。

新块分配时需按 n 预分配内存,平衡内存使用与性能。

控制内存分配粒度,减少碎片化。


8. 关联内存池
c 复制代码
list->pool = pool;

保存内存池指针,用于后续内存分配。


9. 返回成功状态
c 复制代码
return NGX_OK;

通知调用者初始化成功。

明确函数执行结果,便于错误处理。


相关推荐
吴声子夜歌14 小时前
Nginx应用与运维——Nginx在Kubernetes中的应用(一)
运维·nginx·kubernetes
by2099915 小时前
list 的使用:把节点、位置和操作联系起来的综合叙述(上)
数据结构·c++·笔记·list
螺蛳粉 螺蛳粉15 小时前
第一篇:Keepalived 高可用实战:VIP 漂移与 Nginx 主备切换完整指南
运维·nginx·负载均衡·keepalived·高可用
吴声子夜歌16 小时前
Nginx应用与运维——Nginx在Kubernetes中的应用(三)
运维·nginx·kubernetes
小小龙学IT16 小时前
ROS2 安装完全指南(Ubuntu 版):从零开始到跑通第一个节点本文
linux·运维·ubuntu
吴声子夜歌17 小时前
Nginx应用与运维——Nginx在Kubernetes中的应用(二)
运维·nginx·kubernetes
Wang's Blog1 天前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
MicrosoftCloud1 天前
用户权限 04|/etc/sudoers 安全配置:从最小授权到「别把 ALL 随便给人」
运维·安全·ubuntu·sudo·sudoers
Lsetea1 天前
Nginx加载证书时报SSL_CTX_use_PrivateKey_file失败:私钥配对与权限排查
nginx·https·ssl证书·私钥·证书部署
吴声子夜歌1 天前
Nginx应用与运维——Nginx负载均衡应用实战(二)
运维·nginx·负载均衡