24.Nginx监听套接字读事件处理函数ngx_event_accept

本文深入探讨了Nginx中的ngx_event_accept函数,该函数负责处理监听套接字的读事件。文章详细介绍了函数内部的工作流程,帮助读者理解Nginx如何处理新的连接请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面讲过ngx_event_core_module模块的init_process函数ngx_event_process_init会为每个监听套接字的读事件注册处理函数ngx_event_accept,本篇就学习一下在ngx_event_accept函数中到底进行了哪些工作。


/* event/ngx_event_accept.c */

/* 监听套接字的读事件处理函数
 * param ev: 事件指针
 */
void ngx_event_accept(ngx_event_t *ev)
{
    ngx_uint_t             instance, accepted;
    socklen_t              len;
    struct sockaddr       *sa;
    ngx_err_t              err;
    ngx_log_t             *log;
    ngx_pool_t            *pool;
    ngx_socket_t           s;
    ngx_event_t           *rev, *wev;
    ngx_connection_t      *c, *ls;
    ngx_event_conf_t      *ecf;
    ngx_accept_log_ctx_t  *ctx;

    // 获取ngx_event_core_module模块的配置信息ecf
    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);

    if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
        // 如果事件处理模型的标志包含NGX_USE_RTSIG_EVENT
        
        // 置ev->available为1
        ev->available = 1;

    } else if (!(ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)) {
        // 如果事件处理模型的标志不包含NGX_HAVE_KQUEUE_EVENT和NGX_USE_RTSIG_EVENT
        
        // 置ev->available为配置的multi_accept
        ev->available = ecf->multi_accept;
    }

    // 获取事件对应的连接ls
    ls = ev->data;

    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                   "accept on %s, ready: %d",
                   ls->listening->addr_text.data, ev->available);

    ev->ready = 0;
    accepted = 0;
    pool = NULL;

    do {

        if (pool == NULL) {
            // 如果pool为空
            
            // 创建大小为ls->listening->pool_size的内存池pool
            if (!(pool = ngx_create_pool(ls->listening->pool_size, ev->log))) {
                return;
            }
        }

        // 从内存池pool中申请一个大小ls->listening->socklen的内存空间sa,
        // 我们知道这个内存空间是用来存放套接字地址结构的
        if (!(sa = ngx_palloc(pool, ls->listening->socklen))) {
            ngx_destroy_pool(pool);
            return;
        }
        // 从内存池申请一个ngx_log_t结构体大小的内存空间log
        if (!(log = ngx_palloc(pool, sizeof(ngx_log_t)))) {
            ngx_destroy_pool(pool);
            return;
        }
        // 将ls->log拷贝至log, 并置pool->log为log;
        // 从这里我们可以看出pool与连接ls其实是使用的相同日志,
        // 但是却没有直接置pool->log = ls->log,
        // 我的看法是避免两者任意一个的销毁操作也会对log进行释放,
        // 导致另一个的log无法使用
        ngx_memcpy(log, ls->log, sizeof(ngx_log_t));
        pool->log = log;

        // 从内存池pool中申请一个ngx_accept_log_ctx_t结构体大小的内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值