LCOV - code coverage report
Current view: directory - redis/src - ae_epoll.c (source / functions) Found Hit Coverage
Test: redis.info Lines: 53 44 83.0 %
Date: 2012-04-04 Functions: 0 0 -
Colors: not hit hit

       1                 : /* Linux epoll(2) based ae.c module
       2                 :  * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com
       3                 :  * Released under the BSD license. See the COPYING file for more info. */
       4                 : 
       5                 : #include <sys/epoll.h>
       6                 : 
       7                 : typedef struct aeApiState {
       8                 :     int epfd;
       9                 :     struct epoll_event *events;
      10                 : } aeApiState;
      11                 : 
      12                 : static int aeApiCreate(aeEventLoop *eventLoop) {
      13              53 :     aeApiState *state = zmalloc(sizeof(aeApiState));
      14                 : 
      15              53 :     if (!state) return -1;
      16              53 :     state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
      17              53 :     if (!state->events) {
      18               0 :         zfree(state);
      19               0 :         return -1;
      20                 :     }
      21              53 :     state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */
      22              53 :     if (state->epfd == -1) {
      23               0 :         zfree(state->events);
      24               0 :         zfree(state);
      25               0 :         return -1;
      26                 :     }
      27              53 :     eventLoop->apidata = state;
      28              53 :     return 0;
      29                 : }
      30                 : 
      31                 : static void aeApiFree(aeEventLoop *eventLoop) {
      32               0 :     aeApiState *state = eventLoop->apidata;
      33                 : 
      34               0 :     close(state->epfd);
      35               0 :     zfree(state->events);
      36               0 :     zfree(state);
      37                 : }
      38                 : 
      39                 : static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
      40         1066296 :     aeApiState *state = eventLoop->apidata;
      41                 :     struct epoll_event ee;
      42                 :     /* If the fd was already monitored for some event, we need a MOD
      43                 :      * operation. Otherwise we need an ADD operation. */
      44         1066296 :     int op = eventLoop->events[fd].mask == AE_NONE ?
      45         1066296 :             EPOLL_CTL_ADD : EPOLL_CTL_MOD;
      46                 : 
      47         1066296 :     ee.events = 0;
      48         1066296 :     mask |= eventLoop->events[fd].mask; /* Merge old events */
      49         1066296 :     if (mask & AE_READABLE) ee.events |= EPOLLIN;
      50         1066296 :     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
      51         1066296 :     ee.data.u64 = 0; /* avoid valgrind warning */
      52         1066296 :     ee.data.fd = fd;
      53         1066296 :     if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
      54         1066296 :     return 0;
      55                 : }
      56                 : 
      57                 : static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
      58         1066140 :     aeApiState *state = eventLoop->apidata;
      59                 :     struct epoll_event ee;
      60         1066140 :     int mask = eventLoop->events[fd].mask & (~delmask);
      61                 : 
      62         1066140 :     ee.events = 0;
      63         1066140 :     if (mask & AE_READABLE) ee.events |= EPOLLIN;
      64         1066140 :     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
      65         1066140 :     ee.data.u64 = 0; /* avoid valgrind warning */
      66         1066140 :     ee.data.fd = fd;
      67         1066140 :     if (mask != AE_NONE) {
      68         1066026 :         epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
      69                 :     } else {
      70                 :         /* Note, Kernel < 2.6.9 requires a non null event pointer even for
      71                 :          * EPOLL_CTL_DEL. */
      72             114 :         epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
      73                 :     }
      74                 : }
      75                 : 
      76                 : static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
      77         1769701 :     aeApiState *state = eventLoop->apidata;
      78         1769701 :     int retval, numevents = 0;
      79                 : 
      80         3539402 :     retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
      81         1769701 :             tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
      82         1769701 :     if (retval > 0) {
      83                 :         int j;
      84                 : 
      85         1766295 :         numevents = retval;
      86         3876120 :         for (j = 0; j < numevents; j++) {
      87         2109825 :             int mask = 0;
      88         2109825 :             struct epoll_event *e = state->events+j;
      89                 : 
      90         2109825 :             if (e->events & EPOLLIN) mask |= AE_READABLE;
      91         2109825 :             if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
      92         2109825 :             eventLoop->fired[j].fd = e->data.fd;
      93         2109825 :             eventLoop->fired[j].mask = mask;
      94                 :         }
      95                 :     }
      96         1769701 :     return numevents;
      97                 : }
      98                 : 
      99                 : static char *aeApiName(void) {
     100            9168 :     return "epoll";
     101                 : }

Generated by: LCOV version 1.7