ngx_http_run_posted_requests
1 定义ngx_http_run_posted_requests 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.cvoidngx_http_run_posted_requests(ngx_connection_t*c){ngx_http_request_t*r;ngx_http_posted_request_t*pr;for(;;){if(c-destroyed){return;}rc-data;prr-main-posted_requests;if(prNULL){return;}r-main-posted_requestspr-next;rpr-request;ngx_http_set_log_request(c-log,r);ngx_log_debug2(NGX_LOG_DEBUG_HTTP,c-log,0,http posted request: \%V?%V\,r-uri,r-args);r-write_event_handler(r);}}ngx_http_run_posted_requests 函数的作用是 循环消费主请求 posted_requests 链表中的所有延迟请求 依次调用它们的 write_event_handler 驱动请求状态机继续执行 从而实现请求的异步重入、递归控制或安全终止。2 详解1 函数签名voidngx_http_run_posted_requests(ngx_connection_t*c)返回值 返回值类型void 无返回值表明该函数是一个纯粹的执行过程不向调用者反馈操作状态参数 ngx_connection_t *c 指向 当前 连接的结构体2 逻辑流程1 局部变量 2 循环处理1 局部变量{ngx_http_request_t*r;ngx_http_posted_request_t*pr;r 指向当前待处理的 HTTP 请求结构体的指针会在循环中被反复赋值。 pr 指向 posted_requests 链表中某一个节点的指针用于从链表中逐一取出节点。2 循环处理for(;;){if(c-destroyed){return;}rc-data;prr-main-posted_requests;if(prNULL){return;}r-main-posted_requestspr-next;rpr-request;ngx_http_set_log_request(c-log,r);ngx_log_debug2(NGX_LOG_DEBUG_HTTP,c-log,0,http posted request: \%V?%V\,r-uri,r-args);r-write_event_handler(r);}}#1 构建一个无条件无限循环。 该循环会持续从延迟链表中取出请求并执行 直到某个退出条件被触发链表为空或连接已销毁。 意义 因为一个延迟请求的处理过程可能又会 加入 新的请求到链表 所以必须反复消费不能用简单的单次遍历。 无限循环保证了只要还有请求在链表中就能立即得到处理直到队列彻底清空。#2 连接销毁检查 如果连接已被标记为销毁直接退出函数。 在处理一个延迟请求时可能会因为错误或正常关闭导致连接被销毁。 如果连接已经无效继续操作后续请求将会访问野指针因为请求和连接的内存可能已被回收 必须立即停止#3 从连接取回当前请求 获取主请求的延迟链表头 链表为空则退出 将链表头指针更新为当前头节点的下一个节点pr-next即完成头节点的出队操作。 因为 pr 节点即将被处理必须先从链表中将其摘除 先出队再执行是一种典型的做法。 意义保证每个请求只会被执行一次 并且处理期间新 加入 的请求会正确地追加到链表尾部不会被遗漏。# 4 获取节点中保存的实际请求 设置日志上下文 调试日志输出 调用写事件处理函数驱动请求继续运行