Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1838300
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2388
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(184)

文章存档

2021年(26)

2020年(56)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: NOSQL

2019-06-10 10:31:43

ae_epoll,顾名思义,它底层的实现就是epoll(),相比于select(),epoll()的更加优秀,他会把就绪的描述符放到一个链表里面,并返回给调用者(具体是通过eventpoll来实现的,这个后续讲网络编程的时候会详细说下),省去了遍历时间。

 redis当中将epoll()封装如下:

点击(此处)折叠或打开

  1. typedef struct aeApiState {
  2.     int epfd;
  3.     struct epoll_event *events;
  4. } aeApiState;
一般api如下:

点击(此处)折叠或打开

  1. static int aeApiCreate(aeEventLoop *eventLoop) {
  2.     aeApiState *state = zmalloc(sizeof(aeApiState));

  3.     if (!state) return -1;
  4.     state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
  5.     if (!state->events) {
  6.         zfree(state);
  7.         return -1;
  8.     }
  9.     state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */
  10.     if (state->epfd == -1) {
  11.         zfree(state->events);
  12.         zfree(state);
  13.         return -1;
  14.     }
  15.     eventLoop->apidata = state;
  16.     return 0;
  17. }

  18. static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
  19.     aeApiState *state = eventLoop->apidata;

  20.     state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize);
  21.     return 0;
  22. }

  23. static void aeApiFree(aeEventLoop *eventLoop) {
  24.     aeApiState *state = eventLoop->apidata;

  25.     close(state->epfd);
  26.     zfree(state->events);
  27.     zfree(state);
  28. }

  29. static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
  30.     aeApiState *state = eventLoop->apidata;
  31.     struct epoll_event ee = {0}; /* avoid valgrind warning */
  32.     /* If the fd was already monitored for some event, we need a MOD
  33.      * operation. Otherwise we need an ADD operation. */
  34.     int op = eventLoop->events[fd].mask == AE_NONE ?
  35.             EPOLL_CTL_ADD : EPOLL_CTL_MOD;

  36.     ee.events = 0;
  37.     mask |= eventLoop->events[fd].mask; /* Merge old events */
  38.     if (mask & AE_READABLE) ee.events |= EPOLLIN;
  39.     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
  40.     ee.data.fd = fd;
  41.     if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
  42.     return 0;
  43. }

  44. static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
  45.     aeApiState *state = eventLoop->apidata;
  46.     struct epoll_event ee = {0}; /* avoid valgrind warning */
  47.     int mask = eventLoop->events[fd].mask & (~delmask);

  48.     ee.events = 0;
  49.     if (mask & AE_READABLE) ee.events |= EPOLLIN;
  50.     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
  51.     ee.data.fd = fd;
  52.     if (mask != AE_NONE) {
  53.         epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
  54.     } else {
  55.         /* Note, Kernel < 2.6.9 requires a non null event pointer even for
  56.          * EPOLL_CTL_DEL. */
  57.         epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
  58.     }
  59. }
  60. static char *aeApiName(void) {
  61.     return "epoll";
  62. }
核心调用如下:

点击(此处)折叠或打开

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

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

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

  12.             if (e->events & EPOLLIN) mask |= AE_READABLE;
  13.             if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
  14.             if (e->events & EPOLLERR) mask |= AE_WRITABLE;
  15.             if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
  16.             eventLoop->fired[j].fd = e->data.fd;
  17.             eventLoop->fired[j].mask = mask;
  18.         }
  19.     }
  20.     return numevents;
  21. }



阅读(7746) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~