Event handle - wyc902/redis GitHub Wiki

redis 服务器启动以后,会做一些初始化的操作(是否是test模式,sentinle?,载入持久化数据(rdb,aof),是否运行cluster mode 等等),然后进入aeMain函数,调用aeEventLoop进入消息循环。

int main(int argc, char **argv) {
    ....
    aeMain(server.el);
}

void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS);
    }
}
int aeProcessEvents(aeEventLoop *eventLoop, int flags) {
    int processed = 0, numevents;

    /* 如果既不处理文件事件又不处理时间事件,直接return */
    if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) return 0;

    /* 是否处理文件事件,一般情况下会优先处理文件事件 */
    if (eventLoop->maxfd != -1 ||
        ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) {
        struct timeval *tvp;
        ...
        /* 计算 I/O 多路复用的等待时间 tvp */
        ...
        numevents = aeApiPoll(eventLoop, tvp);
        ...
        /* 顺序处理准备好的文件读写事件 */
        for (int 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;

            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++;
        }
    }
    /* 处理时间事件 */
    if (flags & AE_TIME_EVENTS) 
        processed += processTimeEvents(eventLoop);
    return processed;
}

最后返回处理的事件数量