【问题标题】:what do EPOLLERR and EPOLLHUP really mean and how to deal with them?EPOLLERR 和 EPOLLHUP 的真正含义是什么以及如何处理它们?
【发布时间】:2015-05-29 12:40:01
【问题描述】:

我正在阅读 redis 源代码,并在 ae_epoll.c 中找到以下代码:

static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    aeApiState *state = eventLoop->apidata;
    int retval, numevents = 0;

    retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
            tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
    if (retval > 0) {
        int j;

        numevents = retval;
        for (j = 0; j < numevents; j++) {
            int mask = 0;
            struct epoll_event *e = state->events+j;

            if (e->events & EPOLLIN) mask |= AE_READABLE;
            if (e->events & EPOLLOUT) mask |= AE_WRITABLE;

            /* so why set AE_WRITABE when EPOLLERR or EPOLLHUP happend? */
            if (e->events & EPOLLERR) mask |= AE_WRITABLE;
            if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
            eventLoop->fired[j].fd = e->data.fd;
            eventLoop->fired[j].mask = mask;
        }
    }
    return numevents;
}

那么为什么在 EPOLLERR 或 EPOLLHUP 事件发生时设置 AE_WRITABE 呢?我已经阅读了有关 EPOLLERR 和 EPOLLHUP 的手册页,但我无法理解。

EPOLLERR
        Error condition happened on the  associated  file  descriptor.   epoll_wait(2)
        will always wait for this event; it is not necessary to set it in events.

EPOLLHUP
        Hang up happened on the associated file descriptor.  epoll_wait(2) will always
        wait for this event; it is not necessary to set it in events.

【问题讨论】:

  • 看起来像是用 C 编码的,请在您的问题中标记语言。

标签: c linux redis network-programming epoll


【解决方案1】:

那么为什么在 EPOLLERR 或 EPOLLHUP 事件发生时设置 AE_WRITABE?

这大概是为了简化调用aeApiPoll()的代码,例如。 G。在ae.c:aeProcessEvents():

        numevents = aeApiPoll(eventLoop, tvp);
        for (j = 0; j < numevents; j++) {
            aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
            int mask = eventLoop->fired[j].mask;
            int fd = eventLoop->fired[j].fd;
            int rfired = 0;

            /* note the fe->mask & mask & ... code: maybe an already processed
             * event removed an element that fired and we still didn't
             * processed, so we check if the event is still valid. */
            if (fe->mask & mask & AE_READABLE) {
                rfired = 1;
                fe->rfileProc(eventLoop,fd,fe->clientData,mask);
            }
            if (fe->mask & mask & AE_WRITABLE) {
                if (!rfired || fe->wfileProc != fe->rfileProc)
                    fe->wfileProc(eventLoop,fd,fe->clientData,mask);
            }
            processed++;
        }

fe-&gt;wfileProc() 无论如何都必须处理挂起和错误情况,因为它们可能随时发生,包括处理 AE_WRITABLE 事件时;由于没有针对异常情况的单独事件标志,处理循环不需要对它们进行特殊处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 2011-07-06
    • 2017-09-17
    • 1970-01-01
    • 2012-12-15
    相关资源
    最近更新 更多