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;
}
最后返回处理的事件数量