如何处理nginx中的陈旧事件

时间:2017-03-28 15:00:00

标签: nginx

这些天,我正在研究nginx源代码。

但是有一个关于陈旧事件的问题。 如果有即将到来的事件:#1,#2,#3 ..#40, 当我们处理#1时,#40将关闭,它的变量实例为0 和#2.#3是一个新的连接, 接受函数来分配一个只是免费的新描述符(#40), 当我们处理#2时, 我们需要调用名为ngx_event_accept的函数,然后调用ngx_get_connection, 但不幸的是,在那之后,我们失败了,这意味着我们需要释放连接,但是我们已经调用了一次ngx_get_connection,这意味着变量实例已经改变了一次。 就像下面的代码(成功和失败)

void ngx_event_accept(ngx_event_t *ev)
{
    ...
     /* success */
    c = ngx_get_connection(s, ev->log);

    if (c == NULL) {
        if (ngx_close_socket(s) == -1) {
            ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
                          ngx_close_socket_n " failed");
        }

        return;
    }

    c->type = SOCK_STREAM;
    ...
   /* failed */
    c->pool = ngx_create_pool(ls->pool_size, ev->log);
    if (c->pool == NULL) {
        ngx_close_accepted_connection(c);
        return;
    }

    c->sockaddr = ngx_palloc(c->pool, socklen);
    if (c->sockaddr == NULL) {
        ngx_close_accepted_connection(c);
        return;
    }

    ngx_memcpy(c->sockaddr, sa, socklen);
    /*  or failed here */
    log = ngx_palloc(c->pool, sizeof(ngx_log_t));
    if (log == NULL) {
        ngx_close_accepted_connection(c);
        return;
    }
    ....
}

当我们处理#3时,我们成功,fd设置为40,并且实例的值再次改变。 现在它与之前相同,因此名为ngx_epoll_process_events的函数中的以下判断语句将不起作用,

if (c->fd == -1 || rev->instance != instance) {
            /*
             * the stale event from a file descriptor
             * that was just closed in this iteration
             */
            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "epoll: stale event %p", c);
            continue;
}

我知道它可以发布队列中没有处理的事件,但如果我不使用ngx_use_accept_mutex,这意味着函数ngx_process_events_and_timers中的标志不包含NGX_POST_EVENTS, 在这种情况下,它不会发布事件,但会立即处理事件,这是错误的,因为#40是陈旧事件。

0 个答案:

没有答案