• redis源码笔记-ae_epoll.c


    这部分代码是具体事件触发网络库的底层实现。Linux下有epoll设施,而且其效率是现在最高的。注意即使高效如redis,其也只是选择了自动档-水平触发(自动档和手动档的典故请自行google)。据说libevent也是使用的水平触发。废话不多说,看代码吧。

     1 #include <sys/epoll.h>
     2 
     3 typedef struct aeApiState {
     4     int epfd;
     5     struct epoll_event events[AE_SETSIZE]; //存的是epoll_wait返回后得到的事件列表
     6 } aeApiState; //作为eventLoop结构的apidata存储
     7 
     8 static int aeApiCreate(aeEventLoop *eventLoop) {
     9     aeApiState *state = zmalloc(sizeof(aeApiState));
    10 
    11     if (!state) return -1;
    12     state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */
    13     if (state->epfd == -1) return -1;
    14     eventLoop->apidata = state;
    15     return 0;
    16 }
    17 
    18 static void aeApiFree(aeEventLoop *eventLoop) {
    19     aeApiState *state = eventLoop->apidata;
    20 
    21     close(state->epfd);
    22     zfree(state);
    23 }
    24 
    25 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
    26     aeApiState *state = eventLoop->apidata;
    27     struct epoll_event ee;
    28     /* If the fd was already monitored for some event, we need a MOD
    29      * operation. Otherwise we need an ADD operation. */
    30     int op = eventLoop->events[fd].mask == AE_NONE ?
    31             EPOLL_CTL_ADD : EPOLL_CTL_MOD;
    32 
    33     ee.events = 0;
    34     mask |= eventLoop->events[fd].mask; /* Merge old events */
    35     if (mask & AE_READABLE) ee.events |= EPOLLIN;
    36     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
    37     ee.data.u64 = 0; /* avoid valgrind warning */
    38     ee.data.fd = fd;
    39     if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
    40     return 0;
    41 }
    42 
    43 static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
    44     aeApiState *state = eventLoop->apidata;
    45     struct epoll_event ee;
    46     int mask = eventLoop->events[fd].mask & (~delmask);
    47 
    48     ee.events = 0;
    49     if (mask & AE_READABLE) ee.events |= EPOLLIN;
    50     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
    51     ee.data.u64 = 0; /* avoid valgrind warning */
    52     ee.data.fd = fd;
    53     if (mask != AE_NONE) {
    54         epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
    55     } else {
    56         /* Note, Kernel < 2.6.9 requires a non null event pointer even for
    57          * EPOLL_CTL_DEL. */
    58         epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
    59     }
    60 }
    61 
    62 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    63     aeApiState *state = eventLoop->apidata;
    64     int retval, numevents = 0;
    65 
    66     retval = epoll_wait(state->epfd,state->events,AE_SETSIZE,
    67             tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
    68     if (retval > 0) {
    69         int j;
    70 
    71         numevents = retval;
    72         for (j = 0; j < numevents; j++) {
    73             int mask = 0;
    74             struct epoll_event *e = state->events+j;
    75 
    76             if (e->events & EPOLLIN) mask |= AE_READABLE;
    77             if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
    78             eventLoop->fired[j].fd = e->data.fd;
    79             eventLoop->fired[j].mask = mask;
    //在fired数组里注册
    80 } 81 } 82 return numevents; 83 } 84 85 static char *aeApiName(void) { 86 return "epoll"; 87 }
  • 相关阅读:
    HubSpot – 网站开发必备的 jQuery 信息提示库
    Ink – 帮助你快速创建响应式邮件(Email)的框架
    Simptip – 使用 Sass 制作的 CSS Tooltip 效果
    字体大宝库:12款好看的手写艺术字体免费下载
    『摄影欣赏』20幅温馨浪漫的精美照片欣赏【组图】
    Stickup – 轻松实现元素固定效果的 jQuery 插件
    精品素材:15套免费的 Photoshop 自定义图形集
    Node.js 入门手册:那些最流行的 Web 开发框架
    潮流设计:15个创意的 3D 字体版式作品欣赏
    值得拥有!精心推荐几款超实用的 CSS 开发工具
  • 原文地址:https://www.cnblogs.com/liuhao/p/2505491.html
Copyright © 2020-2023  润新知