Event Handle File Event - wyc902/redis GitHub Wiki
通过aeProcessEvents函数我们知道redis server会优先处理文件事件,根据掩码来区分事件是读还是写,然后调用事件创建时候绑定好的函数处理。
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);
}
创建文件事件的函数是
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData) {
aeFileEvent *fe = &eventLoop->events[fd];
if (aeApiAddEvent(eventLoop, fd, mask) == -1)
return AE_ERR;
fe->mask |= mask;
if (mask & AE_READABLE) fe->rfileProc = proc;
if (mask & AE_WRITABLE) fe->wfileProc = proc;
fe->clientData = clientData;
if (fd > eventLoop->maxfd)
eventLoop->maxfd = fd;
return AE_OK;
}
这个函数会传入处理函数的指针,clientData指向一片内存区域,里面存放结构化的要发给客户端的数据或者从客户端接收来的数据。 由于底层的io多路复用模块不同,可以是select,epoll,kqueue等。redis使用eventLoop->aeFiredEvent数组存放已经ready的事件,只要是在这个数组里的事件io已完成可以直接被相关处理函数处理,从而屏蔽底层os实现的不同。
for (j = 0; j < numevents; j++) {
aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
......
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++;
}